Guidefor server owners4 min read
Fixing "Bad packet id" DecoderException in Minecraft
io.netty.handler.codec.DecoderException: java.io.IOException: Bad packet id NN means the server tried to read a packet with the wrong protocol's table. What causes it and the three places to check.
What the error is telling you
io.netty.handler.codec.DecoderException: java.io.IOException: Bad packet id 64
The server received bytes, tried to decode them as a packet, and failed. Specifically, it read an integer expecting a packet id, looked it up in the table for the connection's current state, and found nothing there. Netty throws immediately because at that point the stream is unreadable; there is no way to recover a byte offset once the decoder has guessed wrong.
The number in the message, 64 in this example, is not meaningful on its own. It is whatever
value landed where a packet id was expected. It tells you decoding broke, not which packet
was intended.
Why a valid-looking number can still be wrong
Packet ids are not fixed. Each Minecraft protocol version defines its own table, and each
connection state, handshake, status, login, play, has its own separate table within that
version. Id 0 in the play state of one protocol version can be a completely different
packet in another.
That is the actual failure here. The server is decoding a byte stream written by one protocol version using the packet id table of a different one. The two sides never agreed on a shared protocol number before data started flowing, or something downstream rewrote the connection incorrectly after they did. Either way, the receiving end is reading the wrong table, so numbers that would be valid packet ids under the correct version come out as garbage under the wrong one.
For the full mechanics of how protocol numbers are assigned and where they are listed, see protocol versions explained.
The four real causes
- A genuine client and server version mismatch. The simplest case: two different Minecraft versions with two different protocol numbers, talking directly with no proxy or translation layer in between.
- A stale or misconfigured ViaVersion or ViaBackwards. These plugins translate packets between protocol versions. If the installed build does not know about one of the versions involved, or is misconfigured for it, translation can produce a packet stream the other side cannot decode.
- A corrupted client install. A damaged or partially updated client can send malformed packets that fail decoding on a server that is otherwise correctly matched. Reinstalling the client rules this out.
- A proxy running a different protocol than its backend. In a BungeeCord or Velocity setup, the proxy and the backend server are two separate programs, each with their own Minecraft version. If they disagree, the backend can end up decoding proxy-forwarded packets with the wrong table.
Fix one: match protocol versions exactly
If there is no proxy and no version-translation plugin involved, this is a plain mismatch. Put the client and server on the same Minecraft version, or the same protocol number if you're intentionally running different patch versions that share one. Which versions share a protocol lists every number.
Fix two: check ViaVersion and ViaBackwards
If the server is meant to accept multiple client versions, confirm the bridge plugins are actually current for both versions in play, not just installed.
- Update ViaVersion and ViaBackwards to the latest build for your server's Minecraft version.
- Confirm the client version connecting is inside the range that build claims to support. A version released after the plugin build will not be covered yet.
- Check the plugin's own logs. Both log unsupported protocol versions explicitly, and that message is more specific than the netty exception on its own.
See supporting many client versions for how the bridge is set up correctly in the first place.
Fix three: check your proxy version
If BungeeCord or Velocity sits in front of the server, check both ends independently. A proxy that matches the client is not the same as a proxy that matches the backend.
- Confirm the proxy's supported protocol range covers the backend server's Minecraft version.
- If the backend also runs ViaVersion, make sure the proxy is not translating a connection that the backend then translates again, since double translation is a common source of this exact error.
- Restart the proxy after any version-related config change. Some proxies cache the detected backend protocol at startup and do not re-check it.
How this relates to "Outdated client" and "Outdated server"
Same category of problem, different point in Minecraft's history where it shows up.
Modern Minecraft checks the protocol number during the handshake, before login, and rejects a mismatch with a clean Outdated client or Outdated server message naming which side is behind. See fixing outdated client and outdated server for that error specifically.
This raw netty DecoderException is what a protocol mismatch looked like before that check
existed, on Minecraft versions around and before the 1.8 netty rewrite. A plain vanilla
version mismatch on current Minecraft is caught earlier and produces the clean message
instead.
So if you are seeing this exact exception on a current server, a plain version mismatch is usually not the cause, because that case is already intercepted upstream. It points more specifically at a proxy or a version-translation plugin producing a packet stream the receiving side cannot decode, which is why fixes two and three above are the ones worth checking first.
Checking before it happens again
Three facts settle every case:
- What protocol version the client is on.
- What protocol version the server is on.
- Whether anything between them, a proxy or a translation plugin, is rewriting packets and whether it is current for both versions.
If all three line up, this exception has no reason to occur. If one of them does not, it is the one to fix.

