{"record":{"id":"5e6d40c5fd145c05","repo":"gchq/CyberChef","slug":"incorrect-packet-length-5e6d40","errorCode":null,"errorMessage":"Incorrect packet length.","messagePattern":"Incorrect packet length\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/HASSHServerFingerprint.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/HASSHServerFingerprint.mjs#L50-L86","documentation":"Identical guard to the client variant, but in HASSH Server Fingerprint. The first 4 bytes of the byte stream must equal the stream length minus 4. Used to validate that the supplied bytes form one complete SSH transport record before parsing the server's KEXINIT.","triggerScenarios":"Non-SSH input, a truncated server->client capture, wrong input encoding, or feeding the client's packet to the server operation.","commonSituations":"Direction confusion (client bytes into the server op); incomplete record from a reassembled stream; hex/base64 mismatch on the input format arg; capture grabbed only partial bytes due to MTU fragmentation.","solutions":["Verify Input format matches the encoded bytes.","Feed only the server->client SSH_MSG_KEXINIT record with its 4-byte length prefix.","Check that total byte count == bigEndianUint32(first4Bytes) + 4.","If you only have the payload, prepend the correct 4-byte length."],"exampleFix":"// before: feeding client-direction bytes to the server op\nrun(clientBytes, [\"Hex\", \"Hash\"]);\n// after: use the server-direction record\nrun(serverKexInit, [\"Hex\", \"Hash\"]);","handlingStrategy":"validation","validationCode":"function assertServerSshPacket(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: ${len} vs ${bytes.length-4}`);\n  }\n}","typeGuard":"function isCompleteServerSshPacket(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 = hasshServer.run(hexInput, args);\n} catch (e) {\n  if (e instanceof OperationError && /packet length/i.test(e.message)) {\n    return null; // not a usable server record\n  }\n  throw e;\n}","preventionTips":["Use server->client bytes for the server op.","Match the Input format argument to the byte encoding.","Validate the length field against actual byte count first."],"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"}