gchq/CyberChef · error · OperationError
Incorrect packet length.
Error message
Incorrect packet length.
What it means
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.
Source
Thrown at src/core/operations/HASSHServerFingerprint.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
- 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.
Example fix
// before: feeding client-direction bytes to the server op run(clientBytes, ["Hex", "Hash"]); // after: use the server-direction record run(serverKexInit, ["Hex", "Hash"]);
Defensive patterns
Strategy: validation
Validate before calling
function assertServerSshPacket(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: ${len} vs ${bytes.length-4}`);
}
} Type guard
function isCompleteServerSshPacket(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 = hasshServer.run(hexInput, args);
} catch (e) {
if (e instanceof OperationError && /packet length/i.test(e.message)) {
return null; // not a usable server record
}
throw e;
} Prevention
- 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.
When it happens
Trigger: Non-SSH input, a truncated server->client capture, wrong input encoding, or feeding the client's packet to the server operation.
Common situations: 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.
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/5e6d40c5fd145c05.
Report an issue: GitHub.