ruvnet/ruflo · error
Buffer too small to contain declared header
Error message
Buffer too small to contain declared header
What it means
Thrown by RvfaReader.fromBuffer when the u32LE header length stored at byte offset 8 (after the 4-byte 'RVFA' magic and 4-byte version) plus the 12-byte preamble exceeds the actual buffer length. The RVFA format declares its JSON header size up front; if the file is truncated or the length field is corrupt, the declared header cannot physically fit and the reader aborts before attempting to parse JSON. This is a hard integrity check — the reader never clamps or guesses.
Solutions
- Verify the file size against the source and re-download/rebuild — truncation is the most common cause; confirm the 32-byte SHA256 footer is actually present at the end
- Inspect the preamble: buf.readUInt32LE(8) must be <= buf.length - 12 - 32; if it is enormous, the length field itself is corrupt and the file is unrecoverable
- If you generate RVFA buffers yourself, write headerLen as the exact byte length of the serialized JSON header (see exampleFix)
- Check transfer integrity with checksums (rsync -c, sha256sum on both ends) before retrying
Example fix
// before — declared length doesn't match the JSON actually written const headerJson = Buffer.from(JSON.stringify(header)); preamble.writeUInt32LE(headerJson.length + 64, 8); // padded guess -> truncation read-back // after — declare the exact JSON byte length const headerJson = Buffer.from(JSON.stringify(header)); preamble.writeUInt32LE(headerJson.length, 8); const image = Buffer.concat([preamble, headerJson, sectionData, footer]);
Defensive patterns
Strategy: validation
Validate before calling
import { RVFA_MAGIC, RVFA_VERSION } from './rvfa-format.js';
function canContainHeader(buf: Buffer): boolean {
if (buf.length < 44) return false;
if (!buf.subarray(0, 4).equals(RVFA_MAGIC)) return false;
if (buf.readUInt32LE(4) !== RVFA_VERSION) return false;
const headerLen = buf.readUInt32LE(8);
return headerLen <= 1024 * 1024 && 12 + headerLen <= buf.length - 32;
} Type guard
function isPlausibleRvfa(buf: Buffer): buf is Buffer {
return buf.length >= 44 && 12 + buf.readUInt32LE(8) <= buf.length - 32;
} Try / catch
try {
const reader = RvfaReader.fromBuffer(buf);
} catch (e) {
if (e instanceof Error && e.message === 'Buffer too small to contain declared header') {
// file truncated: re-download, don't retry with the same bytes
}
throw e;
} Prevention
- Always size-check downloads against the published image size before parsing
- When building buffers, write headerLen from the exact byte length of the serialized JSON, not an estimate
- End-to-end checksum artifacts so truncation is caught at transfer time, not parse time
When it happens
Trigger: Calling RvfaReader.fromBuffer(buf) or await RvfaReader.fromFile(path) where readUInt32LE(8) + 12 > buf.length. Concretely: a partially downloaded .rvfa image, a file cut short by a disk-full write, or a hand-assembled buffer whose headerLen field doesn't match the JSON bytes actually appended.
Common situations: Interrupted scp/cp or CI artifact size limits truncating the image; disk-full during appliance build; test fixtures that write the preamble but forget to append the header JSON; a length field written in the wrong endianness or at the wrong offset by custom tooling.
Related errors
- Section " " extends beyond buffer (offset= , size= …
- Header length extends beyond buffer
- Section " " exceeds buffer bounds
- Buffer too small to be a valid RVFA file
- Buffer too small to contain RVFA preamble
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/2048148d6c7d0122.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/appliance/rvfa-format.ts:337
}
// Version
const version = buf.readUInt32LE(MAGIC_SIZE);
if (version !== RVFA_VERSION) {
throw new Error(
`Unsupported RVFA version: ${version} (expected ${RVFA_VERSION})`,
);
}
// Header length
const headerLen = buf.readUInt32LE(MAGIC_SIZE + VERSION_SIZE);
if (headerLen > MAX_HEADER_JSON_SIZE) {
throw new Error(
`Header JSON exceeds maximum size (${headerLen} > ${MAX_HEADER_JSON_SIZE})`,
);
}
if (PREAMBLE_SIZE + headerLen > buf.length) {
throw new Error('Buffer too small to contain declared header');
}
// Parse header JSON
const headerSlice = buf.subarray(PREAMBLE_SIZE, PREAMBLE_SIZE + headerLen);
let parsed: unknown;
try {
parsed = JSON.parse(headerSlice.toString('utf-8'));
} catch {
throw new Error('Failed to parse RVFA header JSON');
}
if (!validateHeader(parsed)) {
throw new Error('RVFA header failed validation');
}
const header = parsed as RvfaHeader;
// Bounds-check every section offset
const totalSize = buf.length;View on GitHub (pinned to fa13ee4ad6)