ruvnet/ruflo · error · Error

Buffer too small for declared header

Error message

Buffer too small for declared header

What it means

Thrown by parsePatchHeader() when PRE(12) + declared header length exceeds the buffer length. The preamble's header-length field claims more JSON than the buffer actually contains, so reading the header slice would run past the end. This catches truncated headers and implausibly large (possibly corrupt) length fields before JSON.parse is attempted.

Source

Thrown at v3/@claude-flow/cli/src/appliance/rvfa-distribution.ts:197

      const signable = Buffer.concat([Buffer.from(canonicalJson(header), 'utf-8'), payload]);
      header.signature = edSign(signable, opts.privateKey);
      header.signedBy = opts.signedBy;
    }
    const hJson = Buffer.from(JSON.stringify(header), 'utf-8');
    const magic = Buffer.from('RVFP');
    const ver = Buffer.alloc(4); ver.writeUInt32LE(RVFP_VERSION, 0);
    const hLen = Buffer.alloc(4); hLen.writeUInt32LE(hJson.length, 0);
    return Buffer.concat([magic, ver, hLen, hJson, payload, sha256B(payload)]);
  }

  static parsePatchHeader(buf: Buffer): RvfpHeader {
    if (buf.length < PRE) throw new Error('Buffer too small for RVFP preamble');
    const magic = buf.subarray(0, 4).toString('ascii');
    if (magic !== 'RVFP') throw new Error(`Invalid RVFP magic: "${magic}"`);
    const ver = buf.readUInt32LE(4);
    if (ver !== RVFP_VERSION) throw new Error(`Unsupported RVFP version: ${ver}`);
    const hLen = buf.readUInt32LE(8);
    if (PRE + hLen > buf.length) throw new Error('Buffer too small for declared header');
    const h = JSON.parse(buf.subarray(PRE, PRE + hLen).toString('utf-8')) as RvfpHeader;
    if (h.magic !== 'RVFP') throw new Error('RVFP header magic mismatch');
    return h;
  }

  static async verifyPatch(buf: Buffer): Promise<PatchVerifyResult> {
    const errors: string[] = [];
    let header: RvfpHeader;
    try { header = RvfaPatcher.parsePatchHeader(buf); } catch (e) {
      const empty: RvfpHeader = {
        magic: 'RVFP', version: 0, targetApplianceName: '', targetApplianceVersion: '',
        targetSection: '', patchVersion: '', created: '', newSectionSize: 0,
        newSectionSha256: '', compression: 'none',
      };
      return { valid: false, header: empty, errors: [(e as Error).message] };
    }
    const { start, end, section } = patchData(buf);
    if (end < start) {

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Re-fetch or regenerate the patch from a known-good source.
  2. Compare the file size against the producer's reported size before parsing.
  3. If you control the producer, log the expected total size alongside the patch for round-trip checks.
  4. Reject files whose preamble header-length field exceeds the remaining buffer size.
Defensive patterns

Strategy: validation

Validate before calling

const RVFP_PRE = 12;
function patchHeaderFits(buf: Buffer): boolean {
  if (buf.length < RVFP_PRE) return false;
  const hLen = buf.readUInt32LE(8);
  return RVFP_PRE + hLen <= buf.length;
}

Try / catch

try {
  const header = RvfaPatcher.parsePatchHeader(buf);
} catch (e) {
  if (/Buffer too small for declared header/.test((e as Error).message)) {
    throw new Error('Patch header region is truncated; re-fetch or regenerate the .rvfp');
  }
  throw e;
}

Prevention

When it happens

Trigger: A patch whose header JSON was truncated after the preamble (e.g. partial download), or a corrupted 4-byte header-length field that encodes an oversized value. The magic and version checks already passed.

Common situations: Interrupted IPFS fetch of a patch; a write that was killed mid-flush; bit-rot on the length field; a patch that was sliced by a proxy with a body-size limit.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/ddce2b3f70b55472. Report an issue: GitHub.