gchq/CyberChef · error · OperationError
Not a known handshake message.
Error message
Not a known handshake message.
What it means
Thrown by the internal parseHandshake() in TLS.mjs when the handshake type byte is neither 0x01 (ClientHello) nor 0x02 (ServerHello). This parser only understands the two hello messages; any other handshake type (Certificate 0x0B, ServerKeyExchange 0x0C, etc.) is rejected in the switch default.
Source
Thrown at src/core/lib/TLS.mjs:100
length: 3,
data: b.getBytes(3),
value: s.readInt(3)
};
if (s.length !== h.handshakeLength.value + 4)
throw new OperationError("Not enough data in Handshake message.");
switch (h.handshakeType.value) {
case 0x01:
h.handshakeType.description = "Client Hello";
parseClientHello(s, b, h);
break;
case 0x02:
h.handshakeType.description = "Server Hello";
parseServerHello(s, b, h);
break;
default:
throw new OperationError("Not a known handshake message.");
}
return h;
}
/**
* Parse a TLS Client Hello
* @param {Stream} s
* @param {Stream} b
* @param {Object} h
* @returns {JSON}
*/
function parseClientHello(s, b, h) {
// Hello version
h.helloVersion = {
description: "Client Hello Version",
length: 2,
data: b.getBytes(2),View on GitHub (pinned to 4290ea7539)
Solutions
- Only pass ClientHello (type 0x01) or ServerHello (type 0x02) handshake messages to this parser.
- If you need other handshake types, this parser does not implement them — use a complete TLS dissector.
- Double-check that the bytes handed to parseTLSRecord start exactly at a handshake record header so the type byte is read from offset 5.
Example fix
// before: passing a Certificate handshake record
parseTLSRecord(certRecordBytes); // type byte 0x0B
// after: filter for hello messages first
if (recordBytes[5] === 0x01 || recordBytes[5] === 0x02) {
parseTLSRecord(recordBytes);
} Defensive patterns
Strategy: validation
Validate before calling
function isHelloHandshake(recordBytes) {
// handshake type byte sits at offset 5 (after the 5-byte TLS record header)
return recordBytes.length >= 6 &&
recordBytes[5] === 0x01 || recordBytes[5] === 0x02;
}
if (!isHelloHandshake(bytes)) {
throw new Error(
`parseTLSRecord only decodes ClientHello (0x01) / ServerHello (0x02). ` +
`Got handshake type 0x${(bytes[5] ?? 0).toString(16)}.`
);
}
const r = parseTLSRecord(bytes); Type guard
function isHelloHandshake(recordBytes) {
return recordBytes.length >= 6 &&
(recordBytes[5] === 0x01 || recordBytes[5] === 0x02);
} Try / catch
try {
record = parseTLSRecord(bytes);
} catch (e) {
if (e instanceof OperationError && /Not a known handshake message/.test(e.message)) {
// skip Certificate/KeyExchange/etc. — this parser only does hellos
continue;
}
throw e;
} Prevention
- Filter records by handshake type before parsing; this parser only handles ClientHello/ServerHello.
- For a full handshake decode, use a complete TLS dissector rather than this hello-only parser.
- Confirm correct byte alignment so offset 5 is genuinely the handshake type.
When it happens
Trigger: Feeding a TLS handshake record whose body is a Certificate, ServerKeyExchange, ServerHelloDone, Finished, or any non-hello message. Also reached when the byte offset is wrong (the type byte is read from the wrong position) or when the record is a hello fragment whose first body byte was misinterpreted.
Common situations: Capturing a full handshake and passing each record to this parser without filtering by handshake type; using the parser to inspect a renegotiation or post-handshake message; misaligned parsing due to a previous length error masking the real type byte.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Not handshake data.
- Not enough data in Handshake message.
- Incorrect handshake length.
- Not handshake data.
- Incorrect handshake length.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/49ae38032a694c75.
Report an issue: GitHub.