Closed most remaining UNCONFIRMED items + caught corrections: 1.7 data[]=proto5, 1.8 multi-block nibble order (z/x), stance y+1.62, 1.15 wolf idx18=begging, 1.18 below-zero sections NOT stripped (claim was wrong), CONTAINER_SLOT_STATE 1.20.3, + pinned first-appeared versions (report details/server links=1.21, fluidCount=26.1, block-state id14=1.19.4, itemCount VarInt=1.20.5). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
13 KiB
Packet Catalog — Control States
Complete packet tables for the small, fully-enumerable states: Handshaking, Status, Login, Configuration.
Baseline: 1.21.1 (protocol 773). Version deltas noted inline. Sources:
minecraft-data/data/pc/1.21.1/protocol.json— IDs and field types (machine-readable ground truth)- ViaVersion
ClientboundLoginPackets.java,ServerboundLoginPackets.java— enum ordinal cross-check- ViaVersion
ClientboundConfigurationPackets1_20_2.java,1_20_5.java,ServerboundConfigurationPackets1_20_2.java,1_20_5.java— version delta cross-check- minecraft.wiki/w/Java_Edition_protocol/Packets — field names and semantic descriptions
See also: ../03-handshake.md · ../04-status-ping.md · ../05-login-encryption.md · ../06-configuration.md
Handshaking State
The handshaking state has no clientbound packets. There is exactly one modern serverbound packet; the legacy ping byte is a legacy artifact that predates the formal state machine.
Serverbound
| ID | Name | Direction | Field summary |
|---|---|---|---|
0x00 |
Handshake | C→S | protocolVersion (VarInt), serverHost (String ≤255), serverPort (u16), nextState (VarInt: 1=Status, 2=Login, 3=Transfer¹) |
0xFE |
Legacy Server List Ping | C→S | payload (u8, always 0x01); pre-1.7 clients only — modern servers recognize and respond with legacy format² |
¹ nextState=3 (Transfer) added in 1.20.5 (protocol 766).
² 0xFE is outside the normal VarInt packet-ID space; servers detect it by the raw byte value.
Source: minecraft-data/data/pc/1.21.1/protocol.json → handshaking.toServer.types mappings {"0x00": "set_protocol", "0xfe": "legacy_server_list_ping"}.
Status State
Two packets in each direction. IDs are stable since 1.7.
Serverbound
| ID | Name | Direction | Field summary |
|---|---|---|---|
0x00 |
Status Request | C→S | No fields; triggers Status Response |
0x01 |
Ping Request | C→S | time (i64, ms timestamp) |
Clientbound
| ID | Name | Direction | Field summary |
|---|---|---|---|
0x00 |
Status Response | S→C | response (String; JSON with version, players, description, favicon) |
0x01 |
Pong Response | S→C | time (i64; echo of Ping Request's timestamp) |
Source: minecraft-data/data/pc/1.21.1/protocol.json → status.toServer / status.toClient mappings.
Login State
Login was extended in 1.20.2 (Login Acknowledged) and 1.20.5 (Cookie Request/Response).
Serverbound
| ID | Name | Direction | Since | Field summary |
|---|---|---|---|---|
0x00 |
Login Start | C→S | 1.7 | username (String ≤16), playerUUID (UUID) |
0x01 |
Encryption Response | C→S | 1.7 | sharedSecret (ByteArray, VarInt-length-prefixed; RSA-encrypted), verifyToken (ByteArray, VarInt-length-prefixed; RSA-encrypted) |
0x02 |
Login Plugin Response | C→S | 1.13 | messageId (VarInt; echoes request), data (optional restBuffer; absent if unhandled) |
0x03 |
Login Acknowledged | C→S | 1.20.2 | No fields; transitions server to Configuration state |
0x04 |
Cookie Response | C→S | 1.20.5 | key (String; resource location), value (optional ByteArray ≤5120 bytes) |
Clientbound
| ID | Name | Direction | Since | Field summary |
|---|---|---|---|---|
0x00 |
Disconnect (Login) | S→C | 1.7 | reason (String; JSON text component) |
0x01 |
Encryption Request | S→C | 1.7 | serverId (String, always "" in modern protocol¹), publicKey (ByteArray; DER-encoded RSA), verifyToken (ByteArray; random nonce), shouldAuthenticate (bool; false = offline-mode) |
0x02 |
Login Success | S→C | 1.7 | uuid (UUID), username (String ≤16), properties (Array of {name:String, value:String, signature:Optional<String>}), strictErrorHandling (bool; added 1.20.5²) |
0x03 |
Set Compression | S→C | 1.8 | threshold (VarInt; packets ≥ this size get compressed; −1 = disable) |
0x04 |
Login Plugin Request | S→C | 1.13 | messageId (VarInt; unique per request), channel (String; resource location), data (restBuffer; plugin-defined payload) |
0x05 |
Cookie Request (Login) | S→C | 1.20.5 | cookie (String; resource location key) |
¹ Server ID was used for session-server auth in very old versions; now always empty string.
² strictErrorHandling field added in 1.20.5 — older clients receive a shorter Login Success.
Source: minecraft-data/data/pc/1.21.1/protocol.json → login.toServer / login.toClient mappings.
ViaVersion cross-check: ClientboundLoginPackets.java ordinals 0–5 match; ServerboundLoginPackets.java ordinals 0–4 match.
Configuration State
Added in 1.20.2 (protocol 764). Not present in 1.20 or earlier.
The Configuration state runs between Login Acknowledged and Finish Configuration. Its purpose: push registry data, feature flags, resource packs, and tags before the client enters Play. The state can be re-entered from Play (server sends Start Configuration).
The packet set expanded again in 1.20.5 (protocol 766): Cookie, Transfer, Store Cookie, resource-pack split (push/pop vs. unified), and Select Known Packs were added, shifting most IDs. 1.21 added Custom Report Details and Server Links (CB 0x0F/0x10, SB 0x08/0x09).
Serverbound
| ID | Name | Direction | Since | Field summary |
|---|---|---|---|---|
0x00 |
Client Information | C→S | 1.20.2 | locale (String ≤16), viewDistance (i8), chatFlags (VarInt), chatColors (bool), skinParts (u8 bitmask), mainHand (VarInt: 0=left,1=right), enableTextFiltering (bool), allowServerListings (bool) |
0x01 |
Cookie Response | C→S | 1.20.5 | key (String; resource location), value (optional ByteArray ≤5120 bytes) |
0x02 |
Plugin Message | C→S | 1.20.2 | channel (String; resource location), data (restBuffer; minecraft:brand → UTF-8 VarInt-prefixed client brand string) |
0x03 |
Acknowledge Finish Configuration | C→S | 1.20.2 | No fields; transitions to Play state |
0x04 |
Keep Alive | C→S | 1.20.2 | keepAliveId (i64; echoes server's value) |
0x05 |
Pong | C→S | 1.20.2 | id (i32; echoes server's Ping id) |
0x06 |
Resource Pack Response | C→S | 1.20.2 | uuid (UUID; 1.20.5+¹), result (VarInt: 0=Success,1=Declined,2=Failed,3=Accepted,4=Downloaded,5=InvalidUrl,6=FailedReload,7=Discarded) |
0x07 |
Select Known Packs | C→S | 1.20.5 | packs (Array of {namespace:String, id:String, version:String}) |
0x08 |
Custom Report Details | C→S | 1.21 | details (Array of {key:String, value:String}; debug crash info)² |
0x09 |
Server Links Response | C→S | 1.21 | links (Array; echoes known-type or custom-text link list)² |
¹ In 1.20.2–1.20.4 the resource pack response had no UUID field; UUID was added when resource-pack-push/pop split was introduced in 1.20.5.
² IDs 0x08 and 0x09 confirmed added in 1.21: absent from ServerboundConfigurationPackets1_20_5 (ends at 0x07) and present in 1.21.1 protocol.json. ViaVersion passes them through in the SB direction without a new enum file — ServerboundConfigurationPackets1_20_5 covers 1.20.5 through 1.21.x (no SB enum file in v1_20_5to1_21 package). Source: ViaVersion/.../protocols/v1_20_5to1_21/packet/ClientboundConfigurationPackets1_21.java (CB side confirmed) + minecraft-data/data/pc/1.21.1/protocol.json configuration.toServer.
ID shift note (1.20.2 → 1.20.5 serverbound):
| ID (1.20.2) | Name | ID (1.20.5+) |
|---|---|---|
0x00 |
Client Information | 0x00 (no change) |
0x01 |
Plugin Message | 0x02 (+1) |
0x02 |
Finish Configuration | 0x03 (+1) |
0x03 |
Keep Alive | 0x04 (+1) |
0x04 |
Pong | 0x05 (+1) |
0x05 |
Resource Pack | 0x06 (+1) |
| — | Cookie Response | 0x01 (new) |
| — | Select Known Packs | 0x07 (new) |
Source: minecraft-data/data/pc/1.21.1/protocol.json → configuration.toServer; ViaVersion/.../ServerboundConfigurationPackets1_20_2.java vs ServerboundConfigurationPackets1_20_5.java.
Clientbound
| ID | Name | Direction | Since | Field summary |
|---|---|---|---|---|
0x00 |
Cookie Request | S→C | 1.20.5 | cookie (String; resource location key to retrieve) |
0x01 |
Plugin Message | S→C | 1.20.2 | channel (String), data (restBuffer; minecraft:brand sends server brand) |
0x02 |
Disconnect | S→C | 1.20.2 | reason (anonymousNbt; text component as NBT, not JSON string) |
0x03 |
Finish Configuration | S→C | 1.20.2 | No fields; server signals config complete, waits for SB Acknowledge |
0x04 |
Keep Alive | S→C | 1.20.2 | keepAliveId (i64; client must echo within ~30s or be kicked) |
0x05 |
Ping | S→C | 1.20.2 | id (i32; client echoes in Pong) |
0x06 |
Reset Chat | S→C | 1.20.2 | No fields; clears client chat session state |
0x07 |
Registry Data | S→C | 1.20.2 | id (String; registry resource location), entries (Array of {key:String, value:Optional<anonymousNbt>}); one packet per registry |
0x08 |
Remove Resource Pack | S→C | 1.20.5 | uuid (optional UUID; absent = remove all) |
0x09 |
Add Resource Pack | S→C | 1.20.5 | uuid (UUID), url (String), hash (String, SHA-1 hex), forced (bool), promptMessage (Optional<anonymousNbt> text component) |
0x0A |
Store Cookie | S→C | 1.20.5 | key (String; resource location), value (ByteArray ≤5120 bytes) |
0x0B |
Transfer | S→C | 1.20.5 | host (String), port (VarInt); redirects client to another server |
0x0C |
Feature Flags | S→C | 1.20.2 | features (Array<String>; resource location list of active experimental features) |
0x0D |
Update Tags | S→C | 1.20.2 | tags (Array of {tagType:String, tags:Array of {tagName:String, entries:Array<VarInt>}}) |
0x0E |
Select Known Packs | S→C | 1.20.5 | packs (Array of {namespace:String, id:String, version:String}); client replies SB Select Known Packs |
0x0F |
Custom Report Details | S→C | 1.21 | details (Array of {key:String, value:String}); appears in crash reports¹ |
0x10 |
Server Links | S→C | 1.21 | links (Array of {hasKnownType:bool, knownType:ServerLinkType (if known), unknownType:NbtComponent (if custom), url:String})¹ |
¹ 0x0F and 0x10 confirmed added in 1.21: ClientboundConfigurationPackets1_20_5 ends at SELECT_KNOWN_PACKS (0x0E); ClientboundConfigurationPackets1_21 (in v1_20_5to1_21 package) adds CUSTOM_REPORT_DETAILS (0x0F) and SERVER_LINKS (0x10). Source: ViaVersion/.../protocols/v1_20_5to1_21/packet/ClientboundConfigurationPackets1_21.java.
ID shift note (1.20.2 → 1.20.5 clientbound):
| ID (1.20.2) | Name | ID (1.20.5+) |
|---|---|---|
0x00 |
Plugin Message | 0x01 (+1) |
0x01 |
Disconnect | 0x02 (+1) |
0x02 |
Finish Configuration | 0x03 (+1) |
0x03 |
Keep Alive | 0x04 (+1) |
0x04 |
Ping | 0x05 (+1) |
0x05 |
Registry Data | 0x07 (+2) |
0x06 |
Resource Pack | split: 0x08/0x09 |
0x07 |
Feature Flags | 0x0C (+5) |
0x08 |
Update Tags | 0x0D (+5) |
| — | Cookie Request | 0x00 (new) |
| — | Reset Chat | 0x06 (new) |
| — | Store Cookie | 0x0A (new) |
| — | Transfer | 0x0B (new) |
| — | Select Known Packs | 0x0E (new) |
Source: minecraft-data/data/pc/1.21.1/protocol.json → configuration.toClient; ViaVersion/.../ClientboundConfigurationPackets1_20_2.java vs ClientboundConfigurationPackets1_20_5.java.