ruvnet/ruflo · error

Failed to parse RVFA header JSON

Error message

Failed to parse RVFA header JSON

What it means

The signing path's parseRvfaBinary could not JSON.parse the header region [12, 12+headerLen). Same root causes as the reader-side error of the same name — corrupt or misaligned header bytes — but hit through signing/verification APIs, which parse more leniently (no full validateHeader pass) yet still require the header to be valid JSON to compute the canonical signing digest.

Solutions

  1. Inspect the header slice: buf.subarray(12, 12 + buf.readUInt32LE(8)).toString('utf8') and find the JSON syntax error position
  2. Rebuild the image with a matching toolchain version — header serialization mismatch between builder and signer is the systematic cause
  3. Avoid ASCII-mode transfers and editors; move .rvfa files as binary only
  4. If signing third-party images, require them pre-parsed/validated before entering the signing step
Defensive patterns

Strategy: try-catch

Validate before calling

const headerLen = buf.readUInt32LE(8);
JSON.parse(buf.subarray(12, 12 + headerLen).toString('utf8')); // pre-check parseability

Try / catch

try { await verifyFile(buf, pub); }
catch (e) {
  if (e instanceof Error && e.message === 'Failed to parse RVFA header JSON') {
    // inspect the slice; likely builder/signer toolchain mismatch
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling sign/verify helpers on an RVFA file whose header bytes aren't valid JSON: truncated header, off-by-N headerLen, re-encoded file. Note the signing digest is computed over canonical header JSON, so a header that parses but was modified is caught later as a signature mismatch instead.

Common situations: CI pipelines signing artifacts produced by a different (older or external) builder whose header serialization differs; files transferred through systems that mangle bytes (FTP ASCII mode); manual header edits that broke JSON syntax before signing.

Understand the failure class

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/cfbb6bfb77eb20e9. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/cli/src/appliance/rvfa-signing.ts:191

  const magic = buf.subarray(0, 4).toString('ascii');
  if (magic !== 'RVFA') {
    throw new Error(`Invalid RVFA magic: expected "RVFA", got "${magic}"`);
  }

  const headerLen = buf.readUInt32LE(8);
  const headerStart = PREAMBLE_SIZE;
  const headerEnd = headerStart + headerLen;

  if (headerEnd > buf.length - SHA256_SIZE) {
    throw new Error('Header length extends beyond buffer');
  }

  const headerJson = buf.subarray(headerStart, headerEnd).toString('utf-8');
  let header: Record<string, unknown>;
  try {
    header = JSON.parse(headerJson) as Record<string, unknown>;
  } catch {
    throw new Error('Failed to parse RVFA header JSON');
  }

  const footer = buf.subarray(buf.length - SHA256_SIZE);
  const sectionData = buf.subarray(headerEnd, buf.length - SHA256_SIZE);

  return { header, headerStart, headerEnd, sectionData, footer };
}

/**
 * Compute the signing digest for an RVFA file.
 *
 * The digest is SHA256 of: canonical_header_json (without signature field)
 *                         + section_data_bytes
 *                         + footer_32_bytes
 */
function computeSigningDigest(
  header: Record<string, unknown>,
  sectionData: Buffer,

View on GitHub (pinned to fa13ee4ad6)