To make a Minecraft server private: run /whitelist on, then /whitelist add PlayerName for each player, and set enforce-whitelist=true in server.properties so anyone not on the list gets kicked even if they are already online. To give a player admin rights, /op PlayerName grants them the level set by op-permission-level (default 4, full control including /stop).

That covers 90% of cases. The remaining 10% is where servers get griefed: knowing what each op level actually allows, what lives in ops.json and whitelist.json, and the settings that quietly undermine the whitelist if you miss them.

Tested on: Minecraft Java Edition 26.2, vanilla server jar and Paper. Everything here is vanilla server behavior, no plugins required. Plugin permission systems (LuckPerms and similar) sit on top of these mechanics, they do not replace them.

Rate4 op levels, each including everything below it
XP levelwhitelist.json and ops.json both key on UUID, not name
Build timeenforce-whitelist kicks in the moment the file reloads
DifficultyBeginner

The whitelist: commands and files

The whitelist is a simple allow-list checked at login. Five commands manage it, all available from the console or from any op with permission level 3+:

whitelist on          turn the whitelist on
whitelist off         turn it off
whitelist add Name    add a player (they must have a paid Java account name)
whitelist remove Name remove a player
whitelist list        show current entries
whitelist reload      re-read whitelist.json after manual edits

The data lands in whitelist.json in the server root: an array of uuid + name pairs. The UUID is the real identity; the name is a convenience copy. This is why whitelisting works through name changes: the server resolves the name to a UUID once, at add time, and checks UUIDs afterwards.

[
  {
    "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",
    "name": "Notch"
  }
]

Do not hand-edit whitelist.json while the server is running. The server keeps its own in-memory copy of the whitelist and only reads the file at startup or on /whitelist reload. Edit the file live and one of two things happens: your edit gets ignored until the next reload, or worse, the server's own next write (which happens on every /whitelist add or /whitelist remove) overwrites the file with its in-memory version, silently discarding whatever you typed. If you must edit by hand, stop the server first, or follow the edit immediately with /whitelist reload and verify with /whitelist list.

Two server.properties keys complete the picture. white-list=true is the same switch as /whitelist on, persisted. enforce-whitelist=true adds the behavior most people expect but do not get by default: per the setting's own description, when this is on and the whitelist reloads, "players not present on the whitelist get kicked from the server." Without it, a removed player stays connected until they log out on their own; the removal only blocks their next join. For a private server, turn both on; the full server.properties guide covers the neighboring settings.

The whitelist only protects you while online-mode=true. With online-mode off, anyone can join under a whitelisted player's name and the server cannot tell the difference. If you run a crossplay setup, Floodgate handles Bedrock identity properly; see our Geyser crossplay guide for how whitelisting Bedrock players works there.

The offline-mode UUID trap

This is the whitelist problem that catches admins who switch modes after their server has already been running. A player's UUID is not one fixed value: Mojang's online UUID (looked up from their account) and the offline UUID (derived locally from their username via a name-based hash) are mathematically different values for the same name. whitelist.json stores whichever kind of UUID the server was generating at the moment each entry was added.

The trap: you run online-mode=true, build a whitelist, every entry gets online UUIDs. Later you flip to online-mode=false for some reason (a proxy setup, testing, whatever), and now the server checks incoming connections against offline UUIDs it computes from the connecting name. Every existing whitelist entry mismatches, and every whitelisted player gets rejected even though their name matches perfectly. The fix is not a whitelist fix: /whitelist remove and /whitelist add each player again after the mode switch, so the file regenerates with UUIDs of the correct kind. Better still, decide your online-mode setting before you start whitelisting anyone, and do not change it later without expecting to redo the list.

This is also why a whitelist copied from a different server, or restored from a very old backup taken under different settings, sometimes fails silently: the UUIDs in the file no longer match what the server computes for those names.

Op permission levels: what 1 through 4 actually grant

/op PlayerName does not grant "admin": it grants the level configured by op-permission-level in server.properties, default 4. The levels stack, each including everything below:

Level 1 bypasses spawn protection. Nothing else. Useful as a builder rank on servers that keep spawn-protection enabled.

Level 2 unlocks the gameplay command set: /gamemode, /give, /tp, /summon, /effect, /enchant, /setblock, /fill, /clone, /time, /weather, /gamerule, /difficulty, /reload, and the ability to use command blocks. This is the level command blocks themselves execute at, and the right level for trusted players who run datapack functions or build with world-edit-style commands. It cannot touch other players' access.

Level 3 adds moderation: /kick, /ban, /ban-ip, /pardon, /pardon-ip, /op, /deop, /whitelist. A level 3 op can manage who is on the server but cannot shut it down. This is the correct level for moderators on any server with more than a couple of admins.

Level 4 adds server control: /stop, /save-off, /save-all, /save-on. Full power, including the ability to pause saving (which matters for safe backups) and stop the process.

The practical advice: on a friends server where everyone trusts everyone, the default level 4 for all ops is fine. The moment you op someone you would not hand your server files to, lower op-permission-level to 3, or better, keep the op list short and give building powers through gamemode or a permissions plugin instead.

Level Adds Typical role
1 Bypass spawn protection Builder on a spawn-protected server
2 Gameplay commands, command blocks Trusted player, function/datapack author
3 Kick, ban, pardon, op, deop, whitelist Moderator
4 Stop, save-off, save-all, save-on Owner

Banning versus whitelisting off: different tools, different jobs

Removing someone from the whitelist and banning them solve different problems, and mixing them up leaves a gap. /whitelist remove Name (with enforce-whitelist=true) kicks them and blocks future joins, but only because the whitelist itself is on. If you ever turn the whitelist off, for an event, for testing, for a public weekend, that player walks straight back in. It is an access-list entry, not a punishment.

/ban Name is the actual punishment: it writes to banned-players.json with a reason, and blocks that UUID regardless of whitelist state. /ban-ip goes further and blocks the connecting IP address itself, which matters against someone who creates alt accounts to get back in; it writes to banned-ips.json instead, keyed by IP rather than UUID. Both are separate from the whitelist entirely; a banned player can still technically appear in whitelist.json (the ban simply overrides it at connection time), so clean up both lists together when someone needs to be fully gone.

/pardon Name reverses a UUID ban. /pardon-ip Address reverses an IP ban. Neither touches the whitelist: pardoning a banned player does not whitelist them back on, and whitelisting a pardoned player is a separate step if the server requires it.

The practical rule: use the whitelist to control who can attempt to join at all, and use bans for people who broke rules and should not be trusted back in even if the whitelist were briefly opened. A server that only whitelists, and never bans troublemakers, relies entirely on the whitelist staying on forever to keep them out.

ops.json: the field nobody knows about

Opping a player writes an entry to ops.json:

[
  {
    "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",
    "name": "Notch",
    "level": 4,
    "bypassesPlayerLimit": false
  }
]

Two things you can only do by editing this file directly (with the server stopped, or followed by a restart):

Per-player levels. The /op command always assigns the global op-permission-level. To have one level 4 owner and two level 3 moderators, op everyone, stop the server, edit each level field, start again. Vanilla has no command for this; it is a file-edit job.

bypassesPlayerLimit. Set to true, this player gets in even when the server is at max-players. Useful for admins of busy public servers who need to investigate problems during peak hours.

The companion files banned-players.json and banned-ips.json follow the same structure with a reason and expiry field, managed by /ban, /ban-ip, and /pardon. All of these files belong in your backup set: reconstructing a ban list from memory is nobody's idea of a weekend.

A lockdown checklist for a private server

Putting it together, a friends server that strangers cannot touch:

  1. online-mode=true (the default; do not change it).
  2. /whitelist on, then /whitelist add each player.
  3. enforce-whitelist=true in server.properties.
  4. Op only people who need it; if any op is not fully trusted, set op-permission-level=3.
  5. enable-rcon=false (the default). If you ever enable RCON for automation, give it a strong password and firewall the port: RCON has full console access.
  6. Do not port-forward anything except the game port (default 25565).
  7. Optional but smart: hide-online-players=true keeps your player list out of public server scanners. Server scanners constantly sweep the IPv4 space for open Minecraft ports, which is exactly how "private" unwhitelisted servers get found and griefed.

If the server is for more than a handful of friends and you start needing ranks, kits, or per-area permissions, that is the point where a Paper server with LuckPerms beats fighting vanilla's four levels. That conversion (vanilla world to Paper) is covered in our server setup guide.

FAQ

How do I whitelist someone on a Minecraft server?

Run /whitelist add TheirName from the console or as a level 3+ op, with /whitelist on active. Set enforce-whitelist=true in server.properties so removals kick players who are already online.

What is the difference between op levels 1, 2, 3, and 4?

Level 1 bypasses spawn protection; level 2 adds gameplay commands like /gamemode and /give; level 3 adds /kick, /ban, /op and /whitelist; level 4 adds /stop and the save commands. Each level includes everything below it.

Can I give different players different op levels?

Yes, but not with a command: op them, stop the server, edit the level field for each entry in ops.json, start the server. The /op command always assigns the global op-permission-level value.

Why can a removed whitelist player still join my server?

Either the whitelist is off (check /whitelist list works and white-list=true in server.properties), or they were online when removed and enforce-whitelist=false, or the server runs online-mode=false, which makes the whitelist trivially spoofable.

Does the whitelist work with name changes?

Yes. whitelist.json stores UUIDs, which never change. The name shown in the file is just a cached label from the moment the player was added.

Why does a whitelisted player suddenly get rejected with no name change?

Almost always an online-mode switch. Online and offline UUIDs are different values for the same name; if the whitelist was built under one mode and the server now runs the other, every entry mismatches. Remove and re-add each player after changing online-mode.

What is the difference between banning a player and removing them from the whitelist?

Removing from the whitelist blocks joining only while the whitelist is on; turn the whitelist off and they can rejoin. A ban blocks that UUID (or, with ban-ip, that IP address) regardless of whitelist state, and needs /pardon or /pardon-ip to reverse.

Can I edit whitelist.json or ops.json directly while the server is running?

You can, but the server keeps its own copy in memory and only re-reads the file at startup or on /whitelist reload. An edit made while the server is running can get silently overwritten by the server's next own write to that file. Stop the server first, or reload immediately after editing.


Updated for Minecraft 26.2 on September 9, 2026. When a new version ships, commands and file formats are re-checked and this log is updated.