gchq/CyberChef · error · OperationError

Need at least 20 bytes for a TCP Header

Error message

Need at least 20 bytes for a TCP Header

What it means

Parse TCP needs at least 20 bytes because the fixed TCP header (source/dest port, seq, ack, offset, flags, window, checksum, urgent pointer) is exactly 20 bytes before options. After converting the input via the chosen format, the operation wraps it in a Stream and refuses to parse if fewer than 20 bytes remain, since reading the header fields would otherwise read past the buffer. This is a precondition guard, not a parse failure of a valid packet.

Source

Thrown at src/core/operations/ParseTCP.mjs:61

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {html}
     */
    run(input, args) {
        const format = args[0];

        if (format === "Hex") {
            input = fromHex(input);
        } else if (format === "Raw") {
            input = Utils.strToArrayBuffer(input);
        } else {
            throw new OperationError("Unrecognised input format.");
        }

        const s = new Stream(new Uint8Array(input));
        if (s.length < 20) {
            throw new OperationError("Need at least 20 bytes for a TCP Header");
        }

        // Parse Header
        const TCPPacket = {
            "Source port": s.readInt(2),
            "Destination port": s.readInt(2),
            "Sequence number": bytesToLargeNumber(s.getBytes(4)),
            "Acknowledgement number": s.readInt(4),
            "Data offset": s.readBits(4),
            "Flags": {
                "Reserved": toBinary(s.readBits(3), "", 3),
                "NS": s.readBits(1),
                "CWR": s.readBits(1),
                "ECE": s.readBits(1),
                "URG": s.readBits(1),
                "ACK": s.readBits(1),
                "PSH": s.readBits(1),
                "RST": s.readBits(1),

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Supply at least 20 bytes of a TCP header (40 hex characters when 'Input format' is Hex).
  2. Verify the 'Input format' arg matches your data: 'Hex' for hex strings, 'Raw' for binary rendered as text.
  3. Strip Ethernet/IP/other lower-layer headers first so the input begins at the TCP header.
  4. Confirm the bytes are actually a TCP segment (e.g. the IP protocol byte is 6) before handing them to this op.

Example fix

// before: only payload / wrong layer
run("4500003c...", ["Hex"])  // IP header -> too short as TCP

// after: TCP header bytes starting at src port
run("0050c06f1f9bbee8...", ["Hex"])  // >= 20 bytes of TCP
Defensive patterns

Strategy: validation

Validate before calling

const FORMAT = args[0];
const bytes = FORMAT === "Hex" ? Buffer.from(input, "hex") : Buffer.from(input, "latin1");
if (bytes.length < 20) throw new Error(`Need >= 20 bytes of TCP header, got ${bytes.length}`);
return parseTcp.run(bytes.toString("latin1"), args);

Type guard

function isTcpHeaderLength(format, input) {
  const bytes = format === "Hex" ? Buffer.from(input, "hex") : Buffer.from(input, "latin1");
  return bytes.length >= 20;
}

Try / catch

try {
  return parseTcp.run(input, [format]);
} catch (e) {
  if (e.message === "Need at least 20 bytes for a TCP Header") {
    // surface a friendlier message, prompt for full header
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling ParseTCP.run with input that decodes to < 20 bytes: a Hex string shorter than 40 hex chars, or a Raw string shorter than 20 characters. Also triggered when the wrong 'Input format' arg is selected so the bytes decode to a too-short buffer, or when a full Ethernet/IP frame is pasted instead of just the TCP segment.

Common situations: Pasting only the TCP payload without the L4 header; pasting a whole captured frame expecting the op to skip lower layers; selecting 'Raw' on hex data (or vice versa) so fromHex/strToArrayBuffer produces garbage of the wrong length; feeding a truncated packet capture.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/0d08eb1c3fac4f9a. Report an issue: GitHub.