{"record":{"id":"0bdc42eed32cdcc3","repo":"gchq/CyberChef","slug":"not-handshake-data-0bdc42","errorCode":null,"errorMessage":"Not handshake data.","messagePattern":"Not handshake data\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/JA3Fingerprint.mjs","lineNumber":64,"sourceCode":"                value: [\"Hash digest\", \"JA3 string\", \"Full details\"]\n            }\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        const handshake = s.readInt(1);\n        if (handshake !== 0x16)\n            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.\");","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/JA3Fingerprint.mjs#L46-L82","documentation":"JA3Fingerprint.run() reads the first byte of the TLS record and requires 0x16 (Handshake content type). Anything else (or undefined when the stream is empty, since Stream.readInt returns undefined past the end) throws. OperationError surfaced as step output.","triggerScenarios":"Input is not a TLS record (HTTP, random bytes), or inputFormat does not match the data so convertToByteArray produced wrong bytes. Also when feeding a record that does not start at a record boundary (mid-stream) or an application-data record (0x17).","commonSituations":"Captured a full TCP stream instead of just the ClientHello; selected 'Hex' but pasted raw text (or vice versa); fed a ServerHello (JA3 not JA3S); started reading after the content-type byte.","solutions":["Verify the first byte equals 0x16; if not, re-slice the input to the record boundary.","Make the inputFormat selector match the actual data (Hex/Base64/Raw).","Capture/extract only the ClientHello record, not the whole session.","If the data is application data (0x17) or another content type, you need a different starting point."],"exampleFix":"// before\nja3.run('GET / HTTP/1.1\\r\\n', ['Latin1','Base64']); // first byte 'G'=0x47 -> Not handshake data.\n// after\nconst rec = hexStartingWith16; // begins 16 03 01 ...\nja3.run(rec, ['Hex','Base64']);","handlingStrategy":"validation","validationCode":"import Utils from \"src/core/Utils.mjs\";\nfunction assertTlsHandshakeRecord(input, inputFormat) {\n  const bytes = Utils.convertToByteArray(input, inputFormat);\n  if (bytes.length < 1) throw new Error('empty input');\n  if (bytes[0] !== 0x16) {\n    throw new Error(`First byte 0x${bytes[0].toString(16)} is not a TLS Handshake (0x16). Check inputFormat and record boundary.`);\n  }\n  return bytes;\n}","typeGuard":"function looksLikeTlsHandshake(bytes) {\n  return bytes.length >= 5 && bytes[0] === 0x16 && bytes[1] === 0x03;\n}","tryCatchPattern":null,"preventionTips":["Verify the first byte is 0x16 before running JA3/JA3S.","Keep inputFormat in sync with the data (Hex/Base64/Raw).","Feed a single record, not a full session.","Capture exactly the ClientHello for JA3."],"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"}