gchq/CyberChef · error · OperationError
Incorrect packet length.
Error message
Incorrect packet length.
What it means
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.
Source
Thrown at src/core/operations/HASSHClientFingerprint.mjs:68
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [inputFormat, outputFormat] = args;
input = Utils.convertToByteArray(input, inputFormat);
const s = new Stream(new Uint8Array(input));
// Length
const length = s.readInt(4);
if (s.length !== length + 4)
throw new OperationError("Incorrect packet length.");
// Padding length
const paddingLength = s.readInt(1);
// Message code
const messageCode = s.readInt(1);
if (messageCode !== 20)
throw new OperationError("Not a Key Exchange Init.");
// Cookie
s.moveForwardsBy(16);
// KEX Algorithms
const kexAlgosLength = s.readInt(4);
const kexAlgos = s.readString(kexAlgosLength);
// Server Host Key Algorithms
const serverHostKeyAlgosLength = s.readInt(4);View on GitHub (pinned to 4290ea7539)
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.
Example fix
// before: input is the KEX payload without the length prefix const payload = captureWithoutLength; run(payload, ["Hex", "Hash"]); // after: prepend the 4-byte big-endian length const len = payload.length / 2; // hex chars to bytes const prefixed = len.toString(16).padStart(8, "0") + payload; run(prefixed, ["Hex", "Hash"]);
Defensive patterns
Strategy: validation
Validate before calling
function assertSshPacket(bytes) {
if (bytes.length < 5) throw new Error('packet too short');
const len = (bytes[0]<<24 | bytes[1]<<16 | bytes[2]<<8 | bytes[3]) >>> 0;
if (bytes.length !== len + 4) {
throw new Error(`length mismatch: header says ${len}, got ${bytes.length-4} payload bytes`);
}
return len;
} Type guard
function isCompleteSshPacket(bytes) {
if (!(bytes instanceof Uint8Array) || bytes.length < 5) return false;
const len = (bytes[0]<<24 | bytes[1]<<16 | bytes[2]<<8 | bytes[3]) >>> 0;
return bytes.length === len + 4;
} Try / catch
try {
hash = hasshClient.run(hexInput, [inputFmt, outFmt]);
} catch (e) {
if (e instanceof OperationError && /packet length/i.test(e.message)) {
// not an SSH record - skip or re-capture
return null;
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Incorrect packet length.
- Not a Key Exchange Init.
- Not a Key Exchange Init.
- Data is not a valid TLS Client Hello. QUIC is not yet suppor
- Data is not a valid TLS Server Hello. QUIC is not yet suppor
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/fd4ff6b8f873fc5e.
Report an issue: GitHub.