can1357/oh-my-pi · error · ArchiveError
Encrypted RAR4 headers are not supported
Error message
Encrypted RAR4 headers are not supported
What it means
Flag bit 0x80 on the RAR4 main header (type 0x73) means the archive's header block is encrypted (password-protected file names, set via 'Encrypt file names' in WinRAR). Without the password and AES decryption of headers, no member can even be enumerated, so the parser throws ArchiveError rather than returning garbage.
Source
Thrown at packages/utils/src/ar/rar.ts:480
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;
let unpackedSize = unpackedLow;View on GitHub (pinned to 9690622007)
Solutions
- Decrypt/extract externally with the password (unrar x -p<password> or 7z x -p<password>) and feed the extracted files to the library.
- Ask the archive creator to re-create it without header encryption (uncheck 'Encrypt file names').
- Repackage decrypted contents as zip/tar.
- Catch ArchiveError and prompt the user for a password / route to an external decryption path.
Example fix
// before
await records(Bun.file("secret.rar")) // header-encrypted
// after
$`unrar x -p$PASS secret.rar out/` // then read out/ files Defensive patterns
Strategy: try-catch
Try / catch
try {
const recs = await records(file);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("Encrypted RAR4 headers")) {
// obtain password, decrypt via unrar -p<pass>, then reprocess
} else throw err;
} Prevention
- Ask archive creators to disable 'Encrypt file names' (header encryption).
- Collect the password at intake if encrypted RAR is expected.
- Route encrypted RAR4 to unrar/7z with -p before parsing.
- Detect the case early: this throws before any entries, so no partial results to clean up.
When it happens
Trigger: Calling records() on a RAR4 archive created with header encryption enabled; the throw happens at the very first main header, before any file entries.
Common situations: Archives shared with 'Encrypt file names' checked and a password; pipelines missing password handling for legacy RAR4; users assuming filename-only listing works without the password.
Related errors
- Encrypted RAR4 file data is not supported
- Encrypted ARJ archives are unsupported
- Encrypted ARJ members are unsupported
- Unsupported RAR4 compression algorithm version ${version}
- Unsupported RAR4 PPMd compressed block
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/201ec30f7d4dcf8f.
Report an issue: GitHub.