pVaults
Personal storage, split into pages. Players type /vault, get a double chest that only they can open, and flip between pages with the arrows at the bottom. Admins can open anyone's vault, online or not.
It runs on Paper, Folia and Fabric, from 1.21.1 all the way to 26.3.
How it works
- A player runs
/vault or /vault 3.
- The page loads from disk in the background, so a big vault never stalls the server.
- The player moves items in and out like any chest. The bottom row is locked and only holds the page arrows.
- Every change is saved a tick after it happens, and again when the vault closes.
Features
- Up to 50 pages. Everyone gets
default-max-pages. Permissions raise it per player or per rank.
- Built not to dupe. On Paper and Folia a page can only be open in one place at a time. On Fabric everyone looking at a page shares one live inventory, the way a chest works.
- Folia support. Every inventory is handled on its viewer's own region thread.
- Crash-safe saves. Files are written to a temp file first and then swapped in, so a crash mid-save can't leave half a vault behind.
- Admin inspection.
/vault view <player> works on offline players too, without freezing the server on a name lookup.
- Fabric build. Same commands and permissions, for dedicated servers and singleplayer worlds.
Where to go next
Setting it up: Install. Changing page counts and messages: config.yml and Permissions. Something off: Troubleshooting.
Install
Requirements
| Platform | Versions | Jar |
| Paper (and forks) | 1.21.1 – 26.3 | pVaults-paper-<version>.jar |
| Folia | 1.21.4 – 26.3 | Same jar as Paper |
| Fabric | 1.21.11 | pVaults-fabric-1.21.11-<version>.jar + Fabric API |
| Fabric | 26.3 | pVaults-fabric-26.3-<version>.jar + Fabric API |
1.21.x servers need Java 21. Anything on 26.x needs Java 25. Spigot and CraftBukkit won't work, since the plugin uses Paper's scheduler and text APIs.
Paper and Folia
- Put
pVaults-paper-<version>.jar in plugins/. One jar covers every Paper and Folia version.
- Start the server.
plugins/pVaults/config.yml is created for you.
- Join and run
/vault.
Fabric
- Install Fabric API.
- Put the pVaults jar that matches your Minecraft version in
mods/. A 1.21.11 jar won't load on 26.3, or the other way round.
- Start the server. The config appears at
config/pvaults.json.
Permissions on Fabric go through fabric-permissions-api, which is bundled inside the jar. LuckPerms for Fabric works straight away. Without a permissions mod, admin commands fall back to permission level 2.
Updating from 1.0.x
Drop in the new jar and restart. Existing vault files are read as they are, no conversion step. The old performance section in config.yml did nothing and can be deleted, though leaving it is harmless.
Opening a vault
Pages
/vault opens page 1. /vault 4 opens page 4, if you have that many. Ask for a page you don't have and you get the invalid-page message, with your highest page in it.
Each page is a six-row chest. The top five rows (45 slots) are storage. The bottom row is the navigation bar: grey panes, a red arrow on the left for the previous page and a green one on the right for the next. The arrows only show up when there's a page to go to.
The navigation row
You can't take, swap, drag or shift-click anything into that row. Clicking an arrow saves the page you're on and opens the next one. Nothing else in the row does anything.
Closing
Close it however you like: Escape, walking away, logging out. Whatever's in the vault at that moment is what gets saved. An item left on your cursor goes back to your inventory, the same as with any chest.
On Paper and Folia, a page can only be open in one place at a time. If an admin is looking at your page 2 and you try to open it, you'll see page-in-use until they close it. Your other pages still open fine.
Viewing other vaults
The command
/vault view Steve
/vault view Steve 7
Needs playervaults.admin. The title shows the owner's name, and anything you change is saved to their vault, not yours.
Offline players
Works the same. The name is looked up in the server's player cache, so it has to be someone who has joined before. Never-seen names get the unknown-player message. On Paper this never touches Mojang's servers. Fabric may ask Mojang for a name that isn't cached yet, but it does that off the server thread, so nothing freezes.
Page limits for admins
Admins can open any page from 1 to 50 in someone else's vault, whatever the owner's own limit is. That's on purpose: if a player loses a rank, the items on their higher pages are still there and an admin can get them back out.
Paper/Folia vs Fabric
On Paper and Folia, viewing a page the owner has open is refused with page-in-use. Two people editing the same items from two Folia region threads at once is exactly how duplication bugs happen, so it simply isn't allowed.
Fabric runs everything on one thread, so there's no such risk. There, admin and owner share the page live. Both see every change as it happens.
config.yml
Paper and Folia only. Lives at plugins/pVaults/config.yml and is applied by /playervaults reload. Fabric uses its own JSON file.
vault
| Key | Default | Meaning |
default-max-pages | 2 | Pages a player gets with no playervaults.pages.<n> node. Clamped to 1–50. |
page-title | <gold>%player_name%'s Vault</gold> <gray>(%page%/%max_pages%)</gray> | Window title, in MiniMessage. %player_name% is the owner. |
reconcile-interval-ticks | 20 | How often an open vault is re-checked in the background, as a safety net on top of the per-click saves. It only writes when something actually changed. Leave it alone unless you know why you're changing it. |
messages
All in MiniMessage. prefix goes in front of every message.
| Key | Sent when | Placeholders |
prefix | Before every message | |
reload | /playervaults reload finished | |
no-permission | Missing playervaults.use or playervaults.admin | |
players-only | /vault run from the console | |
invalid-page | The page number is out of range | <max> |
page-in-use | The page is open somewhere else | |
unknown-player | /vault view for a name that never joined | <name> |
Delete a message key and the built-in default is used. Set it to "" and only the prefix is sent.
Full default file
messages:
prefix: "<gray>[<gradient:#ffcc00:#ffaa00>Vault</gradient>]</gray> "
reload: "<green>Configuration and vaults have been reloaded successfully!</green>"
no-permission: "<red>You do not have permission to do that.</red>"
players-only: "<red>Only players can use vaults.</red>"
invalid-page: "<red>Invalid page. Pages available: 1-<max>.</red>"
page-in-use: "<red>That vault page is already open somewhere else.</red>"
unknown-player: "<red>No player named <name> has played on this server.</red>"
vault:
default-max-pages: 2
page-title: "<gold>%player_name%'s Vault</gold> <gray>(%page%/%max_pages%)</gray>"
reconcile-interval-ticks: 20
Fabric config
config/pvaults.json. Written on first start, and rewritten on every load so options added in newer versions show up in old files. Apply changes with /playervaults reload.
Options
| Key | Default | Meaning |
defaultMaxPages | 2 | Same as default-max-pages on Paper. 1–50. |
pageTitle | &6%player_name%'s Vault &7(%page%/%max_pages%) | Window title. Uses & colour codes, not MiniMessage. |
saveIntervalTicks | 100 | How often changed pages are written to disk. Vaults are also saved whenever one closes and when the server stops. |
messages | see below | Message map, & colour codes. |
Messages
| Key | Sent when | Placeholders |
prefix | Before every message | |
reload | After a reload | |
invalid-page | Page out of range | %max% |
unknown-player | Name never joined | %name% |
load-failed | A vault file couldn't be read | |
There's no page-in-use on Fabric, since pages are shared there, and no no-permission either. Commands you can't use simply don't show up.
Example
{
"defaultMaxPages": 3,
"pageTitle": "&6%player_name%'s Vault &7(%page%/%max_pages%)",
"saveIntervalTicks": 100,
"messages": {
"prefix": "&7[&6Vault&7] ",
"reload": "&aConfiguration reloaded.",
"invalid-page": "&cInvalid page. Pages available: 1-%max%.",
"unknown-player": "&cNo player named %name% has played on this server.",
"load-failed": "&cThat vault could not be loaded, please tell an admin."
}
}
Commands
Reference
| Command | Permission | What it does |
/vault [page] | playervaults.use | Opens your vault. Page 1 if you leave the number off. |
/vault view <player> [page] | playervaults.admin | Opens someone else's vault, online or offline. |
/playervaults reload | playervaults.admin | Reloads the config. Open vaults stay open and keep their contents. |
Tab completion
/vault suggests the page numbers you can open, plus view if you're an admin. After view it lists online players. Offline names still work, you just have to type them.
Console
/playervaults reload works from the console. /vault doesn't, for the obvious reason that the console has no inventory to open it in.
Permissions
All permissions
| Permission | Default | What it allows |
playervaults.use | everyone | Open and use your own vault. |
playervaults.admin | op | /vault view and /playervaults reload. |
playervaults.pages.<n> | see below | Raises your page count to n, up to 50. |
Page permissions
When you open a vault, pVaults checks playervaults.pages.50, then 49, and so on down to one above default-max-pages. The first one you have is your limit. So handing someone playervaults.pages.5 gives them five pages, and if they also have .10, ten wins.
/lp group vip permission set playervaults.pages.5 true
/lp group mvp permission set playervaults.pages.10 true
Take a rank away and the extra pages stop opening. Their items aren't deleted, though. They stay on disk, and an admin can still reach them with /vault view.
Ops on Paper and Folia get all 50 pages. Bukkit gives operators any permission a plugin hasn't declared, and the individual playervaults.pages.<n> nodes aren't declared one by one. On Fabric that doesn't happen. Pages there come only from a permissions mod.
Fabric
Same nodes, checked through fabric-permissions-api. With no permissions mod installed:
playervaults.use is allowed for everyone,
playervaults.admin falls back to permission level 2 (ops),
- page nodes are off for everyone, so all players get
defaultMaxPages.
How saving works
Useful if you're reading vault files from another plugin, or just want to know why pVaults behaves the way it does.
Paper and Folia
Every loaded page lives in an in-memory cache, and that cache is the truth while the server runs. Files on disk follow it.
- Opening a page takes a lease on it for that viewer. A second viewer is refused until the lease is gone.
- The GUI is only ever read or changed on the viewer's own thread (their region thread on Folia, the main thread on Paper).
- One tick after each click or drag, the page is copied into the cache. Copying a tick later matters: the click event fires before the item actually moves.
- Changed pages are queued for writing. Each player's file has at most one write going at a time. Changes that arrive meanwhile are merged into the next one, so two pages of the same file can't overwrite each other.
- The write goes to
<uuid>.yml.tmp first and then replaces the real file in one atomic move.
On shutdown, open vaults are snapshotted and closed, pending writes get up to 10 seconds to finish, and anything left over is written on the spot.
If a vault file can't be parsed, the load fails on purpose and the player is told to contact an admin. Opening an empty vault instead would look friendlier. But the next save would then overwrite the real file with nothing.
Fabric
Each page is a single shared container, like a chest block. Changes mark it dirty. Dirty pages are encoded on the server thread every saveIntervalTicks, and whenever a vault closes, then written by one background thread. Because that thread handles jobs in order, a load can never read a file older than a save that came before it.
Fabric files store the game's data version. After a Minecraft update, items are run through the game's own data fixers on load, the same way world data is upgraded.
Memory
When a player logs out and nobody has any of their pages open, their vault is dropped from memory once it's fully saved. It loads again the next time it's opened.
Data and integration
There's no Java API and no custom events yet. What other plugins can rely on is the commands, the permissions and the file formats below.
File locations
| Platform | Path | Format |
| Paper / Folia | plugins/pVaults/vaults/<uuid>.yml | Bukkit YAML |
| Fabric | <world>/pvaults/<uuid>.dat | Gzipped NBT |
Paper format
One file per player, named by UUID. Pages live under pages. Slots 0–44 hold Bukkit-serialised item stacks, and empty slots are left out.
pages:
'1':
'0':
==: org.bukkit.inventory.ItemStack
DataVersion: ... # the game's data version when it was saved
id: minecraft:diamond
count: 10
'3':
'12':
==: org.bukkit.inventory.ItemStack
...
Reading it from your own plugin:
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(
new File(pVaultsFolder, "vaults/" + uuid + ".yml"));
ConfigurationSection page = yaml.getConfigurationSection("pages.1");
if (page != null) {
for (String slot : page.getKeys(false)) {
ItemStack item = page.getItemStack(slot);
}
}
Don't write to these files while the server is running. pVaults keeps loaded vaults in memory and will save over your edit. Read-only access is fine. Edit offline, or with the server stopped.
Fabric format
{
DataVersion: ..., // the game's data version when it was saved
pages: {
"1": [ { Slot: 0b, id: "minecraft:diamond", count: 10 } ],
"3": [ ... ]
}
}
Each entry is vanilla's ItemStackWithSlot encoding, the same shape a chest uses in a chunk file.
Switching platforms
The two formats are different and there's no converter. A server moving from Paper to Fabric (or back) starts with empty vaults unless the items are moved by hand.
Building from source
Needs JDK 21 and JDK 25. Gradle finds them, or downloads them through foojay.
git clone https://github.com/eyman26/pVaults.git
cd pVaults
./gradlew buildAll
| Task | What it does |
buildAll | Builds every jar into build/dist/. |
:paper:check | Also re-compiles the Paper code against the newest Paper API, to catch removed methods before a server does. |
:paper:runServer / :paper:runFolia | Starts a dev server with the plugin installed. |
Project layout: paper/ is the Paper/Folia plugin, fabric-shared/ holds the Fabric code, and fabric-1.21/ and fabric-26/ build it for each Minecraft version. Versions are pinned in gradle/libs.versions.toml.
FAQ
Why does every op have 50 pages?
That's Bukkit, not pVaults. Operators automatically get any permission that isn't explicitly declared, and the per-number page nodes aren't. If you want ops capped like everyone else, give your op group playervaults.pages.<n> set to false for the numbers above their limit, or use a permissions plugin that doesn't hand ops everything.
Can items be duplicated?
We've worked hard to make that impossible. A page can't be open twice on Paper and Folia. The navigation row can't be clicked into or out of. And saves happen after each click is applied, not before. If you do find a way, report it privately rather than in a public channel.
A player lost a rank. Are their items gone?
No. Pages above their new limit just won't open for them. The items are still in the file, and /vault view <player> <page> gets them back.
Can two people use one vault?
Only through /vault view, which needs admin. There are no shared or team vaults.
Do vaults survive a crash?
Everything up to the last completed click is normally on disk within a moment. A crash can lose at most the last fraction of a second, never the whole file, because writes are swapped in atomically.
Does it work on Spigot?
No. It needs Paper's schedulers and Adventure text API. Any Paper fork, Purpur for example, is fine.
Troubleshooting
Common problems
| Problem | Try this |
| “That vault page is already open somewhere else” | Someone (usually an admin with /vault view) has that page open. It clears the moment they close it, or log out. |
| “Invalid page” | The number is above the player's limit. Check their playervaults.pages.<n> nodes and default-max-pages. |
| “No player named … has played on this server” | The name isn't in the server's player cache. Check the spelling. Players who changed their name need their new one. |
“Your vault could not be loaded” / load-failed | The player's file is damaged. The console names the file and the error. Fix the YAML by hand or restore it from a backup. pVaults won't open it until then, so the real data is never overwritten. |
| “Failed to save vault” in the console | Usually a full disk or wrong folder permissions. pVaults retries on the next change, and the in-memory copy stays intact in the meantime. |
| Plugin won't load on Folia | Make sure it's pVaults 1.1.0 or newer. Older versions aren't marked Folia-compatible. |
| Fabric jar won't load | Check it matches your Minecraft version exactly, and that Fabric API is installed. |
| Players on Fabric only get 2 pages | Page nodes need a permissions mod there. Install LuckPerms for Fabric, or raise defaultMaxPages. |
Known limits
- 45 storage slots per page, 50 pages per player. Neither is configurable.
- No converter between the Paper and Fabric file formats.
- No Java API or events yet.
Support
Questions and bug reports go through the Discord.
Join the Discord
What to include in a report
- Server software and version (Paper, Folia, a fork, or Fabric)
- Your pVaults version
- The console log from start-up, plus anything around the time it went wrong
- For a stuck or broken vault, the player's file from
plugins/pVaults/vaults/
- For a duplication bug, the exact steps. Send them privately.