can1357/oh-my-pi · error · ArchiveError
Unsupported CAB format version ${fixed[25]}.${fixed[24]} (ex
Error message
Unsupported CAB format version ${fixed[25]}.${fixed[24]} (expected 1.3) What it means
CAB stores its format version as major at offset 25 and minor at offset 24. The library only supports version 1.3 (the only version ever defined by the format) and rejects anything else. bytes[24] must be 3 (minor) and bytes[25] must be 1 (major); the message reports the version it found as major.minor.
Source
Thrown at packages/utils/src/ar/cab.ts:259
}
async function readCabArchive(source: ByteSource, options: Parameters<FormatReader>[1]): Promise<ArchiveIndexEntry[]> {
if (source.size < FIXED_HEADER_SIZE) throw new ArchiveError("Invalid CAB archive: truncated CFHEADER");
const fixed = await readExact(source, 0, FIXED_HEADER_SIZE);
if (!hasSignature(fixed)) throw new ArchiveError(`Invalid CAB archive: expected ${CAB_SIGNATURE} signature`);
if (readUInt32LE(fixed, 4) !== 0 || readUInt32LE(fixed, 12) !== 0 || readUInt32LE(fixed, 20) !== 0) {
throw new ArchiveError("Invalid CAB archive: reserved CFHEADER fields must be zero");
}
const cabinetSize = readUInt32LE(fixed, 8);
if (cabinetSize < FIXED_HEADER_SIZE || cabinetSize > source.size) {
throw new ArchiveError("Invalid CAB archive: declared cabinet size is out of bounds");
}
const fileTableOffset = readUInt32LE(fixed, 16);
if (fileTableOffset < FIXED_HEADER_SIZE || fileTableOffset > cabinetSize) {
throw new ArchiveError("Invalid CAB archive: CFFILE table offset is out of bounds");
}
if (fixed[24] !== 3 || fixed[25] !== 1) {
throw new ArchiveError(`Unsupported CAB format version ${fixed[25]}.${fixed[24]} (expected 1.3)`);
}
const folderCount = readUInt16LE(fixed, 26);
const fileCount = readUInt16LE(fixed, 28);
const flags = readUInt16LE(fixed, 30);
if (flags & 0x0003) throw new ArchiveError("Unsupported multi-volume CAB archive (previous/next cabinet link)");
assertEntryCount(folderCount + fileCount, options.limits);
if (folderCount === 0 && fileCount !== 0)
throw new ArchiveError("Invalid CAB archive: files exist without a folder");
let headerReserveSize = 0;
let folderReserveSize = 0;
let dataReserveSize = 0;
let folderTableOffset = FIXED_HEADER_SIZE;
if (flags & 0x0004) {
const reserveHeader = await readExact(source, FIXED_HEADER_SIZE, FIXED_HEADER_SIZE + 4, cabinetSize);
headerReserveSize = readUInt16LE(reserveHeader, 0);
folderReserveSize = reserveHeader[2]!;
dataReserveSize = reserveHeader[3]!;View on GitHub (pinned to 9690622007)
Solutions
- Verify the file with cabextract; a genuinely corrupt version field means the archive must be replaced.
- If you are generating CAB files, ensure offset 24 is 0x03 (minor version 3) and offset 25 is 0x01 (major version 1).
- Check for transfer corruption by comparing checksums against the source of the file.
- If a real future CAB version is required, this library does not support it — use a format-specific tool instead.
Example fix
// before (custom writer) header[24] = 0x01; header[25] = 0x03; // wrong order // after header[24] = 0x03; header[25] = 0x01; // version 1.3, minor then major
Defensive patterns
Strategy: validation
Validate before calling
const buf = new Uint8Array(await Bun.file(path).arrayBuffer());
if (buf[24] !== 3 || buf[25] !== 1) {
throw new Error(`Unsupported CAB version ${buf[25]}.${buf[24]}; only 1.3 is valid`);
} Try / catch
try {
const entries = await readCab(source);
} catch (err) {
if (err instanceof ArchiveError && err.message.startsWith("Unsupported CAB format version")) {
throw new Error("This CAB file claims an invalid/unsupported version and is likely corrupt", { cause: err });
}
throw err;
} Prevention
- Check header bytes 24-25 equal 0x03,0x01 before parsing untrusted files.
- When generating CABs, write minor=3 at offset 24 and major=1 at offset 25.
- Use cabextract as a pre-flight validator for archives from unknown origins.
When it happens
Trigger: Calling readCab() on a signed CAB whose versionReserved fields (offsets 24-25) are not 0x03,0x01 — e.g. bytes overwritten by corruption or a fictional future version number in a crafted file.
Common situations: Fuzzed or malicious archives claiming version 2.x or garbage versions, corrupted files where the version bytes were clobbered, or synthetic test files written by hand-rolled encoders that mis-ordered the version fields (writing 1.3 as major at offset 24).
Related errors
- Invalid CAB archive: expected ${CAB_SIGNATURE} signature
- Invalid CAB archive: reserved CFHEADER fields must be zero
- Invalid CAB archive: files exist without a folder
- Invalid CAB archive: metadata range is out of bounds
- Unable to read CAB archive: ${error instanceof Error ? error
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8d74af00db76928f.
Report an issue: GitHub.