can1357/oh-my-pi · error · ArchiveError
Unsupported RAR4 recovery record
Error message
Unsupported RAR4 recovery record
What it means
The RAR4 main header (type 0x73) with flag bit 0x40 indicates an auxiliary recovery record attached to the archive. parseRar4 does not implement recovery records, so it refuses the archive with ArchiveError. Like the RAR5 RR case, recovery data is repair redundancy, not file content.
Source
Thrown at packages/utils/src/ar/rar.ts:479
const type = bytes[offset + 2]!;
const flags = readUInt16LE(bytes, offset + 3);
const headerSize = readUInt16LE(bytes, offset + 5);
if (headerSize < 7) corrupt("invalid RAR4 header size");
assertIndexSize(headerSize, options.limits, "RAR4 header");
const headerEnd = checkedEnd(offset, headerSize, bytes.byteLength, "RAR4 header");
if ((crc32(bytes.subarray(offset + 2, headerEnd)) & 0xffff) !== headerCrc) corrupt("RAR4 header CRC mismatch");
let dataSize = 0;
let cursor = offset + 7;
if ((flags & 0x8000) !== 0) {
need(cursor, 4, headerEnd, "RAR4 additional size");
dataSize = readUInt32LE(bytes, cursor);
cursor += 4;
}
const dataStart = headerEnd;
let dataEnd = checkedEnd(dataStart, dataSize, bytes.byteLength, "RAR4 data area");
if (type === 0x73) {
if ((flags & 1) !== 0) throw new ArchiveError("Unsupported multi-volume RAR4 archive");
if ((flags & 0x40) !== 0) throw new ArchiveError("Unsupported RAR4 recovery record");
if ((flags & 0x80) !== 0) throw new ArchiveError("Encrypted RAR4 headers are not supported");
sawMain = true;
} else if (type === 0x74) {
need(cursor, 21, headerEnd, "RAR4 file header");
const unpackedLow = readUInt32LE(bytes, cursor);
cursor += 4;
const hostOs = bytes[cursor++]!;
const dataCrc = readUInt32LE(bytes, cursor);
cursor += 4;
const dosTime = readUInt32LE(bytes, cursor);
cursor += 4;
const version = bytes[cursor++]!;
const methodByte = bytes[cursor++]!;
const nameSize = readUInt16LE(bytes, cursor);
cursor += 2;
const attributes = readUInt32LE(bytes, cursor);
cursor += 4;
let packedSize = dataSize;View on GitHub (pinned to 9690622007)
Solutions
- Re-create the archive without a recovery record (omit -rr in rar).
- Open and re-save the archive in WinRAR with recovery record removed.
- Extract with unrar/7-Zip externally and repackage as zip/tar for this library.
- Catch ArchiveError and fall back to an external extractor.
Example fix
// before $`rar a -rr archive.rar files/` // after $`rar a archive.rar files/`
Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot read the main-header flags before parsing; guard by re-packing policy: // if archives come from an untrusted source, test-parse and handle ArchiveError.
Try / catch
try {
const recs = await records(file);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("RAR4 recovery record")) {
// strip recovery record via WinRAR or extract externally
} else throw err;
} Prevention
- Document that -rr archives are unsupported; disable recovery records at creation.
- Normalize incoming archives (repack to zip/tar) at intake.
- Keep an external extractor fallback.
- Surface the flag name from the message to users.
When it happens
Trigger: Calling records() on a RAR4 archive created with 'Add recovery record' enabled (WinRAR -rr, flag 0x40 in the main header).
Common situations: Legacy archives distributed with recovery data for usenet/email transfer; archives protected against bit-rot by the sender; re-shared archives that kept the flag.
Related errors
- Unsupported RAR5 recovery record
- Unsupported multi-volume RAR4 archive
- Unsupported compressed RAR4 symlink '${path}'
- ARJ member '${memberPath}' uses unsupported compression meth
- Encrypted ARJ archives are unsupported
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/9ef5d6e8a35cc1c0.
Report an issue: GitHub.