{"record":{"id":"3136de53b1996f15","repo":"gchq/CyberChef","slug":"not-enough-data-in-client-hello","errorCode":null,"errorMessage":"Not enough data in Client Hello.","messagePattern":"Not enough data in Client Hello\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/JA3Fingerprint.mjs","lineNumber":82,"sourceCode":"            throw new OperationError(\"Not handshake data.\");\n\n        // Version\n        s.moveForwardsBy(2);\n\n        // Length\n        const length = s.readInt(2);\n        if (s.length !== length + 5)\n            throw new OperationError(\"Incorrect handshake length.\");\n\n        // Handshake type\n        const handshakeType = s.readInt(1);\n        if (handshakeType !== 1)\n            throw new OperationError(\"Not a Client Hello.\");\n\n        // Handshake length\n        const handshakeLength = s.readInt(3);\n        if (s.length !== handshakeLength + 9)\n            throw new OperationError(\"Not enough data in Client Hello.\");\n\n        // Hello version\n        const helloVersion = s.readInt(2);\n\n        // Random\n        s.moveForwardsBy(32);\n\n        // Session ID\n        const sessionIDLength = s.readInt(1);\n        s.moveForwardsBy(sessionIDLength);\n\n        // Cipher suites\n        const cipherSuitesLength = s.readInt(2);\n        const cipherSuites = s.getBytes(cipherSuitesLength);\n        const cs = new Stream(cipherSuites);\n        const cipherSegment = parseJA3Segment(cs, 2);\n\n        // Compression Methods","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/JA3Fingerprint.mjs#L64-L100","documentation":"JA3Fingerprint reads the 3-byte handshake length and requires total stream length === handshakeLength + 9 (5 record header + 4 handshake header). A mismatch means the ClientHello body is truncated or carries extra/missing bytes. readInt returning undefined on short input also satisfies the !== check.","triggerScenarios":"A truncated ClientHello (missing extensions/body), a record whose handshake length field is corrupted by an inputFormat mismatch, or extra bytes beyond the handshake body but inside the declared record length. Session ID / cipher suite / extension parsing has not yet started, so the failure is purely about total size.","commonSituations":"Truncated paste of a ClientHello, capture missing the extensions tail, inputFormat mismatch corrupting the 3-byte length, or a record that includes padding the parser does not account for.","solutions":["Ensure the full ClientHello body is present (handshakeLength bytes after the 4-byte handshake header).","Match inputFormat so the 3-byte handshake length field is correct.","Re-capture the ClientHello including all extensions.","Trim the input to exactly handshakeLength + 9 bytes."],"exampleFix":"// before\nja3.run(truncatedClientHello, ['Hex','Base64']); // length mismatch -> Not enough data.\n// after\nconst full = await recaptureFullClientHello();\nja3.run(full, ['Hex','Base64']);","handlingStrategy":"validation","validationCode":"import Utils from \"src/core/Utils.mjs\";\nfunction assertFullClientHello(input, inputFormat) {\n  const b = Utils.convertToByteArray(input, inputFormat);\n  if (b.length < 9) throw new Error('record too short for handshake header');\n  const hsLen = (b[6] << 16) | (b[7] << 8) | b[8];\n  if (b.length !== hsLen + 9) {\n    throw new Error(`Stream length ${b.length} != handshake length ${hsLen}+9. ClientHello is truncated or has extra bytes.`);\n  }\n  return b;\n}","typeGuard":"function isCompleteClientHello(bytes) {\n  if (bytes.length < 9) return false;\n  const hsLen = (bytes[6] << 16) | (bytes[7] << 8) | bytes[8];\n  return bytes[0] === 0x16 && bytes[5] === 1 && bytes.length === hsLen + 9;\n}","tryCatchPattern":null,"preventionTips":["Ensure the full ClientHello body (incl. extensions) is present.","Match inputFormat so the 3-byte length is correct.","Re-capture if extensions are missing.","Trim input to exactly handshakeLength + 9 bytes."],"tags":["tls","network","parsing","cyberchef","input-validation","ja3"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}