can1357/oh-my-pi · error · ArchiveError
Encrypted RAR4 file data is not supported
Error message
Encrypted RAR4 file data is not supported
What it means
Flag bit 2 (0x4) on a RAR4 file header marks the member's packed data as encrypted with a password (AES). The library does not implement RAR crypto decryption, so any encrypted member causes an immediate ArchiveError. Non-encrypted members in the same archive can still be parsed only if no encrypted member is hit first in header order.
Source
Thrown at packages/utils/src/ar/rar.ts:508
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;
if ((flags & 0x100) !== 0) {
need(cursor, 8, headerEnd, "RAR4 high sizes");
packedSize += readUInt32LE(bytes, cursor) * 0x100000000;
cursor += 4;
unpackedSize += readUInt32LE(bytes, cursor) * 0x100000000;
cursor += 4;
dataEnd = checkedEnd(dataStart, packedSize, bytes.byteLength, "RAR4 file data");
}
if ((flags & 3) !== 0) throw new ArchiveError("Unsupported multi-volume RAR4 member");
if ((flags & 4) !== 0) throw new ArchiveError("Encrypted RAR4 file data is not supported");
if (methodByte < 0x30 || methodByte > 0x35)
throw new ArchiveError(`Unsupported RAR4 compression method 0x${methodByte.toString(16)}`);
assertArchivePathBytes(nameSize, "member path", options.limits.maxPathBytes);
need(cursor, nameSize, headerEnd, "RAR4 file name");
const nameBytes = bytes.subarray(cursor, cursor + nameSize);
const rawPath = (flags & 0x200) !== 0 ? decodeRar4UnicodeName(nameBytes) : LATIN1.decode(nameBytes);
cursor += nameSize;
if ((flags & 0x400) !== 0) {
need(cursor, 8, headerEnd, "RAR4 salt");
cursor += 8;
}
let mtimeMs = dosTimeMs(dosTime);
if ((flags & 0x1000) !== 0) {
need(cursor, 2, headerEnd, "RAR4 extended time flags");
const timeFlags = readUInt16LE(bytes, cursor);
cursor += 2;
for (let timeIndex = 0; timeIndex < 4; timeIndex++) {
const mode = (timeFlags >>> ((3 - timeIndex) * 4)) & 15;View on GitHub (pinned to 9690622007)
Solutions
- Decrypt externally with the password: unrar x -p<password> or 7z x -p<password>, then process the extracted files.
- Have the archive creator re-pack without a password.
- Repackage decrypted content as zip/tar.
- Catch ArchiveError and prompt for a password, routing to an external decryption path.
Example fix
// before
await records(Bun.file("locked.rar"))
// after
$`7z x -p$PASS locked.rar -oout/` // then read out/ Defensive patterns
Strategy: try-catch
Try / catch
try {
const recs = await records(file);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("Encrypted RAR4 file data")) {
// decrypt with password via external tool, then reprocess
} else throw err;
} Prevention
- Require unencrypted archives or collect passwords at intake.
- Decrypt with unrar x -p<password> before parsing.
- Consider converting password-protected content to your own encrypted storage format.
- Note: partial parsing stops at the first encrypted member — treat any RAR4 from users as potentially encrypted.
When it happens
Trigger: Calling records() on a password-protected RAR4 archive (WinRAR 'Set password'); throws at the first encrypted file header during enumeration.
Common situations: User-supplied archives protected with a password; CI pipelines lacking the password; archives where only some members are encrypted.
Related errors
- Encrypted RAR4 headers are 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/12f4fe53ddb170f6.
Report an issue: GitHub.