can1357/oh-my-pi · error · ArchiveError
Invalid XZ stream: compressed block size is invalid
Error message
Invalid XZ stream: compressed block size is invalid
What it means
The block's compressed size is derived from the stream index record: unpaddedSize minus header size minus integrity-check size. If that arithmetic is not a safe positive integer, the index record contradicts the header and the stream is invalid. The decoder throws instead of reading a bogus span.
Source
Thrown at packages/utils/src/ar/codecs/xz.ts:456
if ((flags & 0x3c) !== 0) throw new ArchiveError("Unsupported XZ block flags");
const filterCount = (flags & 3) + 1;
const declaredCompressed = (flags & 0x40) !== 0 ? readVarInt(cursor) : undefined;
const declaredUncompressed = (flags & 0x80) !== 0 ? readVarInt(cursor) : undefined;
const filters: XzFilter[] = [];
for (let index = 0; index < filterCount; index++) {
const id = readVarInt(cursor);
const propertySize = readVarInt(cursor);
if (propertySize > cursor.limit - cursor.pos)
throw new ArchiveError("Invalid XZ stream: truncated filter properties");
filters.push({ id, properties: bytes.slice(cursor.pos, cursor.pos + propertySize) });
cursor.pos += propertySize;
}
while (cursor.pos < cursor.limit)
if (bytes[cursor.pos++] !== 0) throw new ArchiveError("Invalid XZ stream: non-zero block header padding");
const integritySize = checkSize(checkId);
const compressedSize = record.unpaddedSize - headerSize - integritySize;
if (!Number.isSafeInteger(compressedSize) || compressedSize <= 0)
throw new ArchiveError("Invalid XZ stream: compressed block size is invalid");
if (declaredCompressed !== undefined && declaredCompressed !== compressedSize)
throw new ArchiveError("Invalid XZ stream: block compressed size mismatch");
if (declaredUncompressed !== undefined && declaredUncompressed !== record.uncompressedSize)
throw new ArchiveError("Invalid XZ stream: block uncompressed size mismatch");
const compressedStart = offset + headerSize;
const compressedEnd = compressedStart + compressedSize;
const paddingSize = (4 - ((headerSize + compressedSize) & 3)) & 3;
const checkStart = compressedEnd + paddingSize;
if (checkStart + integritySize > bytes.byteLength) throw new ArchiveError("Invalid XZ stream: truncated block data");
const last = filters[filters.length - 1]!;
if (last.id !== 0x21 || last.properties.byteLength !== 1)
throw new ArchiveError(`Unsupported XZ terminal filter ID 0x${last.id.toString(16)} (LZMA2 required)`);
let output = await lzma2Decompress(
last.properties[0]!,
bytes.subarray(compressedStart, compressedEnd),
record.uncompressedSize,
);
if (output.byteLength !== record.uncompressedSize)View on GitHub (pinned to 9690622007)
Solutions
- Verify the archive with `xz -t`; a corrupted index usually means the whole file is unusable — re-download it.
- Do not splice or concatenate XZ streams/blocks manually; keep whole streams intact.
- If you control the producer, ensure the stream index accurately records unpadded/uncompressed sizes per block.
- Wrap decompression in error handling so corrupt archives surface as clean failures rather than crashes.
Defensive patterns
Strategy: try-catch
Validate before calling
if (!isXz(bytes)) throw new Error('Not an XZ stream');
if (bytes.byteLength === 0) throw new Error('Empty archive buffer'); Try / catch
try {
return await xzDecompress(bytes, maxOutput);
} catch (err) {
if (err instanceof ArchiveError) {
logger.error('XZ index/header inconsistent', { message: err.message });
return null;
}
throw err;
} Prevention
- Keep XZ streams whole — never splice blocks or indexes between files.
- Validate archives at ingest time and fail fast on corruption.
- Watch storage health: repeated index corruption suggests disk issues.
- Use the standard xz tool to produce archives consumed by this decoder.
When it happens
Trigger: xzDecompress processes a block whose index record's unpaddedSize is smaller than headerSize + integritySize (or yields a non-integer), so compressedSize computes to <= 0 or non-safe-integer.
Common situations: Corrupted stream indexes (bit rot), archives assembled by splicing blocks from different streams, or truncated files whose index was reconstructed incorrectly.
Related errors
- Invalid XZ stream: block compressed size mismatch
- Invalid XZ stream: block uncompressed size mismatch
- Invalid XZ stream: non-canonical variable-length integer
- Unsupported XZ block flags
- Invalid XZ stream: truncated filter properties
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/9d40b5960fb717f9.
Report an issue: GitHub.