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 1.21.4, 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.

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.

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: when the whitelist changes, anyone online who is no longer on it gets kicked immediately. Without enforcement, a removed player stays connected until they log out on their own. 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.

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, 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, /pardon, /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.

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.


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