can1357/oh-my-pi · error · ArchiveError

Invalid CPIO archive: unsupported or corrupt magic at offset

Error message

Invalid CPIO archive: unsupported or corrupt magic at offset ${offset}

What it means

parseHeader recognizes four CPIO header formats: old binary (0xC771/0x71C7), new ASCII '070701', CRC '070702', and portable ASCII '070707'. If the first bytes at the current parse offset match none of these, it throws ArchiveError with the byte offset. This is the format-detection failure: the data is not a supported CPIO header, is corrupt, or parsing has drifted onto a non-header offset.

Source

Thrown at packages/utils/src/ar/cpio.ts:185

	}
	if (magic === "070707") {
		requireRange(bytes, offset, offset + ODC_HEADER_SIZE, "portable ASCII header");
		const field6 = (fieldOffset: number, name: string): number =>
			parseDigits(bytes, offset + fieldOffset, 6, 8, name);
		return {
			headerSize: ODC_HEADER_SIZE,
			alignment: 1,
			devMajor: 0,
			devMinor: field6(6, "device"),
			inode: field6(12, "inode"),
			mode: field6(18, "mode"),
			nlink: field6(36, "link count"),
			mtime: parseDigits(bytes, offset + 48, 11, 8, "modification time"),
			nameSize: field6(59, "name size"),
			fileSize: parseDigits(bytes, offset + 65, 11, 8, "file size"),
		};
	}
	throw new ArchiveError(`Invalid CPIO archive: unsupported or corrupt magic at offset ${offset}`);
}

function decodeUtf8(bytes: Uint8Array): string | undefined {
	try {
		return UTF8_FATAL_DECODER.decode(bytes);
	} catch {
		return undefined;
	}
}

function validateZeroPadding(bytes: Uint8Array, start: number, end: number, what: string): void {
	for (let offset = start; offset < end; offset++) {
		if (bytes[offset] !== 0) throw new ArchiveError(`Invalid CPIO archive: non-zero ${what} padding`);
	}
}

function makeLinkTarget(recordPath: string, targetBytes: Uint8Array, maxPathBytes: number): LinkTarget {
	assertArchivePathBytes(targetBytes.byteLength, "link target", maxPathBytes);

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the input is a CPIO stream: check leading bytes for '070701'/'070702'/'070707' or use sniffCpio
  2. For RPM files, decompress the payload (rpm2cpio | gunzip/xz) before parsing
  3. If the error occurs mid-parse, an earlier entry is malformed — regenerate the archive with standard cpio tooling
  4. Check you are not passing a compressed stream where an uncompressed one is expected

Example fix

// before: feeding a gzip-compressed cpio directly
const entries = await readCpio(source, options);
// after: sniff and decompress first
const head = new Uint8Array(await source.slice(0, 6));
if (!sniffCpio(head)) throw new Error('not a plain CPIO stream; decompress or convert first');
const entries = await readCpio(source, options);
Defensive patterns

Strategy: type-guard

Validate before calling

import { sniffCpio } from '<lib>/ar/cpio';
const head = new Uint8Array(await source.slice(0, 6));
if (!sniffCpio(head)) throw new Error(`not a CPIO stream, magic=${Buffer.from(head).toString('ascii')}`);

Type guard

function looksLikeCpio(head: Uint8Array): boolean {
  const m = Buffer.from(head.subarray(0, 6)).toString('latin1');
  return m === '070701' || m === '070702' || m === '070707' ||
    (head[0] === 0xc7 && head[1] === 0x71) || (head[0] === 0x71 && head[1] === 0xc7);
}

Try / catch

try {
  const entries = await readCpio(source, options);
} catch (err) {
  if (err instanceof ArchiveError && err.message.includes('unsupported or corrupt magic')) {
    // wrong format: dispatch to tar/ar reader or decompress first
  } else throw err;
}

Prevention

When it happens

Trigger: readCpio/readRpmArchive/entries called on non-CPIO data (tar, ar, raw bytes); the very first bytes are not a CPIO magic; mid-stream drift after a malformed entry caused the offset to land on file data or padding rather than the next header; a supported-but-unusual variant (e.g. '070703') not implemented.

Common situations: Passing an uncompressed file where a cpio stream was expected, or vice versa (RPM payloads are gzip/xz-compressed cpio — must be decompressed first); feeding a TAR file to the CPIO reader; truncated archives whose trailer is missing so the loop runs into trailing garbage.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f444c0bf5a0c91bb. Report an issue: GitHub.