{"record":{"id":"205307e5d0ab7283","repo":"gchq/CyberChef","slug":"need-8-bytes-for-a-udp-header","errorCode":null,"errorMessage":"Need 8 bytes for a UDP Header","messagePattern":"Need 8 bytes for a UDP Header","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/ParseUDP.mjs","lineNumber":59,"sourceCode":"    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {Object}\n     */\n    run(input, args) {\n        const format = args[0];\n\n        if (format === \"Hex\") {\n            input = fromHex(input);\n        } else if (format === \"Raw\") {\n            input = Utils.strToArrayBuffer(input);\n        } else {\n            throw new OperationError(\"Unrecognised input format.\");\n        }\n\n        const s = new Stream(new Uint8Array(input));\n        if (s.length < 8) {\n            throw new OperationError(\"Need 8 bytes for a UDP Header\");\n        }\n\n        // Parse Header\n        const UDPPacket = {\n            \"Source port\": s.readInt(2),\n            \"Destination port\": s.readInt(2),\n            \"Length\": s.readInt(2),\n            \"Checksum\": \"0x\" + toHexFast(s.getBytes(2))\n        };\n        // Parse data if present\n        if (s.hasMore()) {\n            UDPPacket.Data = \"0x\" + toHexFast(s.getBytes(UDPPacket.Length - 8));\n        }\n\n        return UDPPacket;\n    }\n\n    /**","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ParseUDP.mjs#L41-L77","documentation":"The UDP header is fixed-size at exactly 8 bytes: source port, destination port, length, and checksum (2 bytes each). Parse UDP wraps the decoded input in a Stream and requires at least 8 bytes before reading those fields; fewer bytes means the header is incomplete and reading would underflow.","triggerScenarios":"Calling ParseUDP.run with input that decodes to fewer than 8 bytes: a Hex string shorter than 16 hex chars, or a Raw string shorter than 8 chars. Also when the wrong 'Input format' is chosen so the decoded length is wrong, or when payload-only / lower-layer data is supplied.","commonSituations":"Pasting only the UDP payload; supplying a full IP packet expecting the op to find the UDP header; selecting the wrong input format causing mis-decode; truncated packet data.","solutions":["Provide at least 8 bytes of a UDP header (16 hex characters for 'Hex' format).","Match the 'Input format' arg to your data ('Hex' vs 'Raw').","Strip IP/lower-layer headers so input begins at the UDP header.","Verify the bytes actually carry UDP (IP protocol 17) before parsing."],"exampleFix":"// before: payload only\nrun(\"68656c6c6f\", [\"Hex\"]);  // 5 bytes -> throws\n\n// after: 8-byte UDP header\nrun(\"00350035...\", [\"Hex\"]);  // >= 8 bytes","handlingStrategy":"validation","validationCode":"const FORMAT = args[0];\nconst bytes = FORMAT === \"Hex\" ? Buffer.from(input, \"hex\") : Buffer.from(input, \"latin1\");\nif (bytes.length < 8) throw new Error(`Need >= 8 bytes of UDP header, got ${bytes.length}`);\nreturn parseUdp.run(input, args);","typeGuard":"function isUdpHeaderLength(format, input) {\n  const bytes = format === \"Hex\" ? Buffer.from(input, \"hex\") : Buffer.from(input, \"latin1\");\n  return bytes.length >= 8;\n}","tryCatchPattern":"try {\n  return parseUdp.run(input, [format]);\n} catch (e) {\n  if (e.message === \"Need 8 bytes for a UDP Header\") {\n    // prompt for the full 8-byte header\n  }\n  throw e;\n}","preventionTips":["Validate decoded byte length >= 8 before calling.","Match Input format to data encoding.","Strip IP/lower-layer headers upstream."],"tags":["networking","udp","input-validation","length-check"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}