Operator is not a role. It is total control - stop the server, edit the world, grant operator to somebody else - and handing it out because a friend needed to change the time of day is how servers get wrecked by people who meant well. The setup that works is three things: a whitelist so there are no strangers, a permissions plugin so ranks are groups rather than a list of exceptions, and exactly as few operators as the server actually needs, which is usually one.
This post covers all three with the real files and the real commands: whitelist.json and ops.json, the four operator levels and why Bukkit ignores most of them, LuckPerms from install to a working group ladder, the nodes you will type most often, and how to find out which permission is actually missing instead of guessing.
Operator is not a permission system#
Vanilla has four operator levels, set per player in ops.json:
| Level | What it unlocks |
|---|---|
| 1 | Bypasses spawn protection. Nothing else |
| 2 | /gamemode, /give, /tp, /summon, /setblock, /effect, /gamerule, command blocks |
| 3 | /ban, /kick, /op, /deop, /whitelist, /pardon |
| 4 | /stop, /save-off, /debug - everything |
[ { "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5", "name": "Notch", "level": 2, "bypassesPlayerLimit": false }]/op <player> always grants at the level in op-permission-level in server.properties, which defaults to 4. To give somebody level 2 you edit the file. function-permission-level (default 2) is the separate level that functions and datapacks run at, and bypassesPlayerLimit lets that player in when the server is full.
Here is the part that makes the whole tier system close to useless on a real server: Bukkit, Spigot and Paper do not honour the levels for plugin permissions. Almost every plugin declares its permissions with a default of op, which means any operator has all of them regardless of whether they are level 1 or level 4. Op your new moderator at level 2 to be careful and you have also given them WorldEdit, every EssentialsX command, and the ability to roll back the world with CoreProtect.
So the rule is simple and it is worth being strict about it. Operators are for the person who administers the box. Everybody else - moderators, builders, donors, trusted regulars - gets a group in a permissions plugin and no operator status at all. When you need to run something once, run it from the panel console: the console is always level 4 and holds every permission, so you never need to op yourself for a single command. Reading the console covers what else it is good for, and the server command cheatsheet has the commands themselves.
The whitelist, exactly#
A whitelisted server has no griefing problem because it has no strangers. For a server run for friends, that one setting replaces most of the plugin list people install instead. It is the cheapest moderation there is.
white-list=trueenforce-whitelist=trueonline-mode=truewhite-list turns it on. enforce-whitelist is the one people miss: with it false, turning the whitelist on or reloading it does not remove anyone who is already connected, so the player you just took off the list stays until they log out. Set it true and a reload kicks everyone not on the list immediately.
| Command | What it does |
|---|---|
whitelist on / whitelist off | Toggles enforcement, and writes white-list back to the properties file |
whitelist add <name> | Looks the name up, resolves the UUID, appends to whitelist.json |
whitelist remove <name> | Removes the entry |
whitelist list | Prints the current names |
whitelist reload | Re-reads whitelist.json from disk after a hand edit |
The file itself is small:
[ { "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5", "name": "Notch" }]Two behaviours worth knowing. Operators bypass the whitelist entirely, which is convenient and also means an old operator entry is a way in that the whitelist will not close - audit ops.json when you audit the whitelist. And whitelist off does not clear the list, so turning it back on restores exactly the same set of people; there is no reason to delete entries when opening the server for an event.
UUIDs, offline mode and the whitelist that will not work
whitelist add works for a player who has never joined because the server asks Mojang for the UUID behind the name. That lookup needs the server to reach the internet, and it needs the name to exist. "That player does not exist" is almost always a typo, a name that was changed, or a Bedrock gamertag being typed at a Java server.
With online-mode=false nothing is verified. UUIDs are generated from the username instead of being issued by Mojang, so a whitelist entry written while online-mode was on will not match the same player after you switch it off, and anybody can connect as any name that is on the list. Offline mode belongs behind a proxy with proper forwarding and nowhere else. If you are running one, read what a reverse proxy does and get the forwarding secret right before you touch online-mode.
Bedrock players arriving through Geyser and Floodgate are a third case: they get a generated UUID and a prefixed username, so pasting their gamertag into whitelist.json by hand will not match. Floodgate ships its own whitelist command for exactly this reason - Geyser and Bedrock crossplay has the setup.
LuckPerms: groups, then permissions, then people#
LuckPerms is the permissions plugin. Install is a jar in plugins/ and a restart; it works on Paper, Velocity, Fabric, Forge and NeoForge, and it stores its data in an H2 file under plugins/LuckPerms/ by default. That default is fine for one server. If you run several that should share ranks, change storage-method in plugins/LuckPerms/config.yml to a SQL backend and point it at the credentials from the panel's database slot; a single shared store beats copying files between servers every time.
The model is three layers, and keeping them separate is the entire trick:
- A group holds permissions.
- A group can inherit another group, so you describe the difference rather than repeating the list.
- A user is put into a group and given nothing directly.
Define a small number of groups, give each the specific commands it needs, and put people in groups. It takes twenty minutes once and saves you from a list of individual exceptions nobody can audit six months later. The moment you find yourself granting a node to one person, ask what group that person is really in.
lp creategroup trustedlp creategroup moderatorlp creategroup adminlp group trusted parent add defaultlp group moderator parent add trustedlp group admin parent add moderatorlp group trusted setweight 10lp group moderator setweight 50lp group admin setweight 100lp user Alex parent set moderatordefault is the group everyone is in and cannot be deleted. Weight decides which group's prefix and suffix win when somebody is in several; it has nothing to do with which permissions apply, which is decided by inheritance and by explicit false nodes beating inherited true ones.
/lp editor is worth knowing about before you type fifty permission set commands. It uploads your current setup to a one-time web page, you drag permissions around in a table, and you paste the code back as /lp applyedits <code>. Nothing is public and nothing is stored beyond the edit. The full tour is in the LuckPerms guide.
A group ladder that works#
Four groups cover almost every community. Add more only when someone can say which specific permission the new group has that the one below it does not.
| Group | Who | What they can do |
|---|---|---|
default | Everyone | Play. Chat, /spawn, one home |
trusted | Regulars, after a while | Quality-of-life commands, more homes, kits |
moderator | Staff | Kick, mute, tempban, inspect who did what |
admin | You, and maybe one other | Everything except the panel account |
lp group default permission set essentials.spawn truelp group default permission set essentials.home truelp group default permission set essentials.sethome truelp group trusted permission set essentials.sethome.multiple.trusted truelp group trusted permission set essentials.tpa truelp group trusted permission set essentials.back truelp group moderator permission set essentials.kick truelp group moderator permission set essentials.mute truelp group moderator permission set essentials.vanish truelp group moderator permission set coreprotect.inspect truelp group moderator permission set coreprotect.lookup truelp group admin permission set coreprotect.rollback truelp group admin permission set worldedit.* trueThree deliberate choices in that list. Moderators can look at the block log but not roll it back, because a rollback with the wrong radius is worse than the grief it was meant to undo. Nobody below admin gets WorldEdit, because WorldEdit is a world editor and an accident with //set is permanent. And essentials.gamemode is in neither list - creative mode on a survival server is an admin decision every time, not a convenience.
The permission nodes you will actually type#
Nodes are plugin-specific, so the authoritative list is always the plugin's own page. These are the ones that come up constantly:
| Node | Gives |
|---|---|
minecraft.command.<name> | A vanilla command on Paper, e.g. minecraft.command.gamemode |
essentials.tp, essentials.tphere | Teleport to and summon players |
essentials.home, essentials.sethome.multiple.<group> | Homes, and how many |
essentials.kit.<name> | One named kit |
essentials.kick, essentials.ban, essentials.mute | The moderation trio |
essentials.vanish | Log in without announcing it |
coreprotect.inspect, coreprotect.lookup | Read the block log |
coreprotect.rollback, coreprotect.restore | Change the world with it |
worldedit.* | All of WorldEdit |
luckperms.* | Manage permissions, including their own |
Two tricks that save time. A node set to false beats the same node inherited as true, so you can build moderator on top of trusted and then take one thing back:
lp group moderator permission set essentials.tphere falseAnd a whole plugin can be switched off for a group in one line by negating its wildcard, then switching individual commands back on. That is usually cleaner than listing thirty nodes.
Contexts, tracks and time-limited access#
Contexts attach a permission to a condition - a world, a server in a proxy network, a game mode. They are how one LuckPerms setup serves a survival world and a creative world without two sets of groups:
lp group builder permission set worldedit.* true world=creativelp group default permission set essentials.fly true world=creativeTracks are an ordered list of groups, which turns promotion into one command and makes the ladder visible:
lp createtrack memberslp track members append defaultlp track members append trustedlp track members append moderatorlp user Sam promote membersTemporary grants are the underrated feature. A guest builder for a weekend, a moderator covering while you are away, a donor rank with a month on it - all of them expire on their own, which means you do not have to remember to remove them:
lp user Sam parent addtemp moderator 14dlp user Guest permission settemp worldedit.* true 48hThat habit is the same one worth having on the hosting account itself, where access should be granted for as long as the job takes and no longer. Subusers and least privilege makes the same argument about the panel.
When somebody says they do not have permission#
Do not guess the node. LuckPerms will tell you which one was checked:
lp verbose onHave the player run the command that fails, then:
lp verbose pasteYou get a link listing every permission check that happened, who it was for, the node, and whether it returned true or false. The failing node is in there, spelled correctly, including the ones with a name or a number baked into them like essentials.sethome.multiple.5. Switch it off afterwards with lp verbose off, because it is chatty.
Other checks, in the order they usually pay off:
lp user <name> infoshows their groups, their weight, their prefix, and any temporary entries with a countdown.lp group <group> permission infolists what that group actually holds, including inherited nodes.lp user <name> permission check <node>answers the direct question.
The four causes behind most of these tickets: the player is an operator so plugin defaults grant them everything and your groups are not doing anything; a second permissions plugin is installed and the two are fighting - pick one; the node is granted in a context that does not match the world they are standing in; or Vault is missing, so the chat plugin cannot read the prefix even though the permissions are correct.
Panel access is a different question#
In-game rank and hosting access are two separate systems, and conflating them is a real risk. A moderator needs to mute people. They do not need to be able to delete the server, read the billing page, or download the world.
On RE:NODE that separation is built in. A role holds permissions - console only, files only, no billing - a team holds people, and a grant joins a team to a server. Access can be time-boxed, invitations go out by link, join code or email, and every server keeps its own activity log, so "who restarted it at 2am" has an answer. Give your builder the file manager and nothing else; give your co-owner console and backups; keep billing to yourself. Add two-factor on the account and the worst case stops being catastrophic.
The same logic applies to RCON. If a Discord bot needs to run commands, it gets an RCON password on a restricted port, not an operator account - using RCON safely covers what that costs you if you get it wrong. And before you open the server to strangers at all, the rest of the list is in the SMP launch checklist and grief protection and anti-cheat.
FAQ#
Do I need a permissions plugin if I only play with friends?
If everyone is trusted and nobody needs commands, no - a whitelist and one operator is a complete setup. Install LuckPerms the first time you want someone to have /tp without also having /stop, which for most groups is about a month in.
Does the whitelist stop people who already joined?
Only with enforce-whitelist=true. With it off, the whitelist is checked at login, so anyone currently connected stays connected until they disconnect. Turn it on and whitelist reload removes them the moment you say so.
How do I whitelist someone who has never played on my server?
whitelist add <name> is enough. The server resolves the UUID from the name itself, so they do not need to join first. It fails only if the name is misspelled, the account does not exist, or the server cannot reach the internet.
Can a player be an operator and still be restricted by LuckPerms?
Not in any way you can rely on. Operator status satisfies the op default that most plugin permissions use, so an op passes almost every check before your groups are consulted. Deop your staff and give them a group instead.
What happens to permissions when the server restarts?
They persist - LuckPerms writes to its own storage immediately, not at shutdown. The files that are rewritten at shutdown are the vanilla ones: ops.json, whitelist.json and the ban lists. Edit those with commands, or with the server stopped.
Should moderators be able to roll back the world?
Give them the lookup and inspect permissions and keep the rollback for admins. Reading the log is how you find out what happened; rolling back is a destructive edit with a radius and a time window, and getting either wrong undoes legitimate building along with the grief.




Comments
Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.