{"record":{"id":"39c2970503fbaf73","repo":"Pumpkin-MC/Pumpkin","slug":"user-data-len-exceeds-1mb-limit","errorCode":null,"errorMessage":"user_data_len exceeds 1MB limit","messagePattern":"user_data_len exceeds 1MB limit","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/pumpkin-protocol/src/bedrock/network_item.rs","lineNumber":52,"sourceCode":"    }\n}\n\nimpl PacketRead for NetworkItemDescriptor {\n    fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {\n        let id = VarInt(i32::from(i16::read(buf)?));\n        let stack_size = u16::read(buf)?;\n        let aux_value = VarUInt::read(buf)?;\n\n        let has_net_id = bool::read(buf)?;\n        if has_net_id {\n            let _net_id = VarInt::read(buf)?;\n        }\n\n        let block_runtime_id = VarInt(VarUInt::read(buf)?.0 as i32);\n\n        let user_data_len = VarUInt::read(buf)?.0 as usize;\n        if user_data_len > 1_048_576 {\n            return Err(Error::new(\n                ErrorKind::InvalidData,\n                \"user_data_len exceeds 1MB limit\",\n            ));\n        }\n        let mut user_data = vec![0u8; user_data_len];\n        buf.read_exact(&mut user_data)?;\n\n        let (nbt_data, place_on_blocks, destroy_blocks, shield_blocking_tick) =\n            read_user_data(user_data, id.0 == i32::from(BedrockItem::SHIELD.id))?;\n\n        Ok(Self {\n            id,\n            stack_size,\n            aux_value,\n            block_runtime_id,\n            nbt_data,\n            place_on_blocks,\n            destroy_blocks,","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-protocol/src/bedrock/network_item.rs#L34-L70","documentation":"Raised while reading a Bedrock network item's user data: the VarUInt-prefixed length field claims more than 1,048,576 bytes (1MB). The reader rejects it before allocating the buffer, protecting against corrupted or malicious packets that would otherwise trigger huge allocations.","triggerScenarios":"Deserializing a network item (read path at network_item.rs:52) where the user_data_len varint exceeds 1MB — caused by stream desync, corrupt data, or crafted packets.","commonSituations":"Malicious client sends an inflated length field; packet parsing drifted out of sync so a data byte is misread as a length; corrupted save/network data.","solutions":["Confirm the packet stream is being read from the correct offset — desync makes garbage bytes look like lengths.","Ensure the client/server protocol versions match; mismatched versions change item encoding.","Treat it as a malformed-packet signal: drop the packet/connection rather than retrying the same bytes.","If sending side, keep user data under 1MB and clamp before writing."],"exampleFix":"// before\nlet data = read_item_user_data(buf)?; // panics/allocs on huge len\n// after\nmatch read_item_user_data(buf) {\n    Ok(d) => d,\n    Err(e) if e.kind() == ErrorKind::InvalidData => { disconnect(\"malformed item\"); }\n    Err(e) => return Err(e),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match NetworkItem::read(buf) {\n    Ok(item) => item,\n    Err(e) if e.to_string().contains(\"1MB limit\") => {\n        log::warn!(\"malformed item packet rejected\");\n        drop_packet();\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep item user data under 1MB when writing.","On this error, suspect stream desync — validate prior field reads.","Verify client/server protocol version parity."],"tags":["protocol","bedrock","deserialization","malformed-packet"],"backgroundTag":"payload-too-large","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}