{"record":{"id":"fd4ff6b8f873fc5e","repo":"gchq/CyberChef","slug":"incorrect-packet-length","errorCode":null,"errorMessage":"Incorrect packet length.","messagePattern":"Incorrect packet length\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/HASSHClientFingerprint.mjs","lineNumber":68,"sourceCode":"            }\n        ];\n    }\n\n    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {string}\n     */\n    run(input, args) {\n        const [inputFormat, outputFormat] = args;\n\n        input = Utils.convertToByteArray(input, inputFormat);\n        const s = new Stream(new Uint8Array(input));\n\n        // Length\n        const length = s.readInt(4);\n        if (s.length !== length + 4)\n            throw new OperationError(\"Incorrect packet length.\");\n\n        // Padding length\n        const paddingLength = s.readInt(1);\n\n        // Message code\n        const messageCode = s.readInt(1);\n        if (messageCode !== 20)\n            throw new OperationError(\"Not a Key Exchange Init.\");\n\n        // Cookie\n        s.moveForwardsBy(16);\n\n        // KEX Algorithms\n        const kexAlgosLength = s.readInt(4);\n        const kexAlgos = s.readString(kexAlgosLength);\n\n        // Server Host Key Algorithms\n        const serverHostKeyAlgosLength = s.readInt(4);","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/HASSHClientFingerprint.mjs#L50-L86","documentation":"Thrown by HASSH Client Fingerprint while parsing the binary SSH packet. The first 4 bytes are the packet length; the operation asserts that stream length equals that value plus 4 (the length field excludes itself). Any byte stream that is not a complete SSH transport-layer packet trips this guard before the message code is even read.","triggerScenarios":"Feeding a non-SSH byte stream, a truncated capture, a reassembled TCP stream missing bytes, or a packet from the wrong direction (server->client instead of client->server). Also triggered by base64/hex input when the input format argument does not match.","commonSituations":"Wrong input format selection (e.g. Hex bytes while the arg expects raw); copying only the KEX_INIT payload without its 4-byte length prefix; capturing post-handshake SSH traffic; feeding the entire TCP session rather than a single record.","solutions":["Confirm the Input format argument matches how your bytes are encoded (Hex, Base64, Raw).","Extract only the client->server SSH_MSG_KEXINIT record, including its 4-byte length prefix.","Re-export the packet from Wireshark via 'Follow TCP Stream' -> 'client side only' and trim to the first record.","Verify the byte count: total bytes must equal (first 4 bytes as big-endian uint32) + 4."],"exampleFix":"// before: input is the KEX payload without the length prefix\nconst payload = captureWithoutLength;\nrun(payload, [\"Hex\", \"Hash\"]);\n// after: prepend the 4-byte big-endian length\nconst len = payload.length / 2; // hex chars to bytes\nconst prefixed = len.toString(16).padStart(8, \"0\") + payload;\nrun(prefixed, [\"Hex\", \"Hash\"]);","handlingStrategy":"validation","validationCode":"function assertSshPacket(bytes) {\n  if (bytes.length < 5) throw new Error('packet too short');\n  const len = (bytes[0]<<24 | bytes[1]<<16 | bytes[2]<<8 | bytes[3]) >>> 0;\n  if (bytes.length !== len + 4) {\n    throw new Error(`length mismatch: header says ${len}, got ${bytes.length-4} payload bytes`);\n  }\n  return len;\n}","typeGuard":"function isCompleteSshPacket(bytes) {\n  if (!(bytes instanceof Uint8Array) || bytes.length < 5) return false;\n  const len = (bytes[0]<<24 | bytes[1]<<16 | bytes[2]<<8 | bytes[3]) >>> 0;\n  return bytes.length === len + 4;\n}","tryCatchPattern":"try {\n  hash = hasshClient.run(hexInput, [inputFmt, outFmt]);\n} catch (e) {\n  if (e instanceof OperationError && /packet length/i.test(e.message)) {\n    // not an SSH record - skip or re-capture\n    return null;\n  }\n  throw e;\n}","preventionTips":["Confirm input encoding matches the Input format argument before invoking.","Validate total bytes == bigEndianUint32(first4) + 4 before passing.","Feed one complete record at a time, not a full TCP session."],"tags":["ssh","hassh","fingerprinting","binary-parsing","packet-length"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}