gchq/CyberChef · error · Error

Exhausted Buffer

Error message

Exhausted Buffer

What it means

Thrown by Protobuf._parse when, after consuming all fields, the internal offset has overshot this.LENGTH — meaning a varint, length-delimited block, or fixed-size field claimed more bytes than the buffer actually held. The raw (schemaless) decoder refuses to silently truncate.

Source

Thrown at src/core/lib/Protobuf.mjs:375

    // Private Class Functions

    /**
     * Main private parsing function
     *
     * @private
     * @returns {Object}
     */
    _parse() {
        let object = {};
        // Continue reading whilst we still have data
        while (this.offset < this.LENGTH) {
            const field = this._parseField();
            object = this._addField(field, object);
        }
        // Throw an error if we have gone beyond the end of the data
        if (this.offset > this.LENGTH) {
            throw new Error("Exhausted Buffer");
        }
        return object;
    }

    /**
     * Add a field read from the protobuf data into the Object. As
     * protobuf fields can appear multiple times, if the field already
     * exists we need to add the new field into an array of fields
     * for that key.
     *
     * @private
     * @param {Object} field
     * @param {Object} object
     * @returns {Object}
     */
    _addField(field, object) {
        // Get the field key/values
        const key = field.key;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Verify the input is complete and well-formed protobuf (re-encode with a known-good library and compare).
  2. Check length-delimited prefixes against the actual remaining bytes before decode.
  3. Strip trailing padding/garbage so offset lands exactly on this.LENGTH.

Example fix

// before: a length prefix says 10 bytes but only 4 remain
// after: correct the length prefix to the real payload size
Defensive patterns

Strategy: validation

Validate before calling

function wellFormedProtobuf(bytes) {
  try { new Protobuf(bytes)._parse(); return true; } catch { return false; }
}

Try / catch

try {
  return new Protobuf(input)._parse();
} catch (e) {
  if (/Exhausted Buffer/.test(e.message)) {
    // input is truncated or a length prefix lies — re-acquire the full payload
  }
  throw e;
}

Prevention

When it happens

Trigger: Decoding bytes where a length-delimited field declares N bytes but fewer remain; a varint runs past the end; a fixed32/fixed64 read crosses the buffer boundary; corrupted/truncated protobuf payload.

Common situations: Hand-edited hex that miscounts a length prefix; partial network frame; concatenation bug leaving a stray trailing byte that looks like a field header; feeding non-protobuf binary.

Related errors


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