Taking Down Servers with a Bad Selector
How a simple bug in command tab completion could crash almost any Minecraft server.
Taking Down Servers with a Bad Selector
About 2 years ago, a significant server crash exploit became public. It targeted a core Minecraft system: command parsing and tab completion. The bug was found by my good friend Thorioum, and for a while, it was a major threat to any server that hadn't patched against it.
The exploit works by sending a malicious packet to request command completions. This system is meant to help players by suggesting possible commands or arguments when they press tab. But with a carefully crafted input, you could turn this helpful feature into a weapon.
How Command Completion Works
When you type "/tell" or any vanilla command that tab completes players and press tab, your client sends a RequestCommandCompletionsC2SPacket to the server. This packet contains your current cursor position and the text of the command you've typed so far.
The server's job is to parse that text, figure out where you are in the command syntax, and send back a list of valid suggestions. To do this, the server must partially execute the command parser on the text you sent.
This is where the trouble starts. The parser has to evaluate everything in the command string you provide, including complex selectors like @a[nbt={}].
The Crack in the Parser
The core of the exploit is a malformed NBT tag inside a player selector.
Look at this command: /tell @a[nbt={C:[[[[[[[[[...]]]]]]]]]]]
An NBT tag like C:[[[[[]]]]] is invalid. The key C expects a value, but it's just given more opening brackets. This isn't valid JSON or NBT format.
Normally, if you tried to run this command, the server would reject it immediately with a syntax error. But the tab completion system works differently. It tries to parse the command to understand its structure and provide suggestions, even if the command is invalid.
When the server's parser hits this malformed NBT, it doesn't fail fast. Instead, it gets stuck in a deep recursion - trying to parse an infinitely nested structure created by all those brackets. This causes a StackOverflowError, crashing the entire server thread.
The Exploit Code
The clever part of the exploit is sending this malicious string specifically through the tab completion system, not the regular command system. Here's a simplified look at how it works:
The attacker builds a string that starts like a real command but ends with the malformed selector: /tell @a[nbt={C:
Then, they append hundreds or thousands of opening brackets: [. The packet sent to the server requests completions for this obviously broken command.
Because the server must try to parse it to provide suggestions, it immediately hits the recursion and crashes. The attacker never needs to execute the command - just asking for help with it is enough.
Here's some example code:
private void selectorCrash(String command, boolean namespace, int length) {
String begin = "/" + (namespace ? "minecraft:" : "") + command + " @a[nbt={C:";
int repeatCount = length - begin.length();
if(repeatCount < 1) return;
String cmd = begin + "[".repeat(repeatCount);
mc.getNetworkHandler().sendPacket(new RequestCommandCompletionsC2SPacket(Random.create().nextBetween(1000,Integer.MAX_VALUE), cmd));
}This builds the malicious string, ensuring it's exactly the right length to maximize damage, and sends it as a tab completion request.
Why this was so dangerous
- No Permissions Required - Players didn't need any special permissions. Any player could potentially crash your server.
- Instant Effect - The crash happened as soon as the packet was processed, with no delay.
- Wide Impact - This affected almost all Minecraft server software (Vanilla, Paper, Spigot, etc.) because it targeted core Minecraft parsing code.
The Aftermath and Fix
Server maintainers quickly released patches once this exploit became public. The fix was to add proper validation in the tab completion parser, checking for excessively nested structures and failing early before a stack overflow could occur.
PaperMC, for example, added recursion depth limits to their NBT parser specifically for tab completion requests. Other server software implemented similar protections.