can1357/oh-my-pi · error · ArchiveError
Not a valid tar archive: missing terminating zero block
Error message
Not a valid tar archive: missing terminating zero block
What it means
This library validates that a tar archive ends with the two consecutive 512-byte zero blocks required by the tar format. If it reaches the end of the data without having seen that terminator, it refuses to index the archive and throws this ArchiveError. It is a structural integrity check: tar archives without the terminator are considered malformed or truncated, not merely odd.
Source
Thrown at packages/utils/src/ar/tar.ts:573
entry.storage = { type: "link", targetPath: portableLinkName, resolveTarget: false };
addEntry(entry);
continue;
}
addEntry(entry, { kind, targetPath });
continue;
}
if (typeFlag !== "0" && typeFlag !== "\0" && typeFlag !== "7" && typeFlag !== "S") continue;
assertArchiveMemberSize(displaySize, normalizedPath, limits);
addEntry({
path: normalizedPath,
isDirectory: false,
size: displaySize,
mtimeMs,
mode,
storage: { type: "member", source: new TarMemberSource(buffer, dataOffset, sparse) },
});
}
if (!sawTerminator) throw new ArchiveError("Not a valid tar archive: missing terminating zero block");
resolvePendingLinks(entries, pendingLinks, limits);
return [...entries.values()];
}
/** Read and index a tar source after one bounded whole-stream read. */
export const readTar: FormatReader = async (source, options) => {
assertInMemorySize(source.size, options.limits);
let bytes: Uint8Array;
try {
bytes = await readAllBytes(source);
} catch (error) {
if (error instanceof ArchiveError) throw error;
throw new ArchiveError(error instanceof Error ? error.message : "Failed to read tar archive");
}
if (bytes.byteLength !== source.size) throw new ArchiveError("Invalid archive: truncated data");
return readTarEntriesFromBuffer(bytes, options);
};
View on GitHub (pinned to 9690622007)
Solutions
- Re-obtain or re-extract the archive; the source is truncated — verify byte size against the upstream checksum
- Rebuild the tar with a standard tool (`tar -cf`) so the terminating zero blocks are written
- Pad the buffer manually with two 512-byte zero blocks if you control generation and know the data is otherwise complete
- Check the producer: if you write tars yourself, append two zeroed 512-byte blocks after the last member
Example fix
// before: hand-rolled writer omits the terminator blocks.push(...memberBlocks); await Bun.write(out, blocks); // after: append the required two zero blocks const terminator = new Uint8Array(2 * 512); await Bun.write(out, [blocks, terminator]);
Defensive patterns
Strategy: validation
Validate before calling
function isTerminatedTar(bytes: Uint8Array): boolean {
if (bytes.byteLength % 512 !== 0) return false;
const end = bytes.byteLength - 1024;
if (end < 0) return false;
return bytes.subarray(end).every((b) => b === 0);
}
if (!isTerminatedTar(bytes)) throw new Error("tar archive lacks terminating zero blocks"); Try / catch
try {
const entries = await readTar(source, options);
} catch (err) {
if (err instanceof ArchiveError && err.message.includes("missing terminating zero block")) {
// treat as corrupted/truncated download: re-fetch or surface to user
} else throw err;
} Prevention
- Verify checksums (sha256) of downloaded archives before reading
- Use standard tar tooling to produce archives — never hand-roll the terminator
- When piping, wait for the writer process to exit before reading the file
When it happens
Trigger: Calling readTar (or readTarEntriesFromBuffer) on a byte buffer that ends after the last file's data blocks without the terminating zero blocks — e.g. a tar written by a custom/naive writer, a stream cut off mid-archive, or a tar concatenated with padding stripped.
Common situations: Downloads interrupted before completion, pipes closed early (curl ... | tar-like flows captured partially), hand-rolled tar writers that forget the terminator, archives produced by tools emitting 'streaming' tar without end-of-archive markers, files truncated on disk after a crash.
Related errors
- Invalid tar octal value: ${value}
- Truncated embedded addon archive entry: ${filename}
- Unsafe embedded addon archive entry: ${filename}
- Unsupported embedded addon archive entry type ${typeflag}: $
- Invalid CAB archive: truncated data
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c8b95641057667f0.
Report an issue: GitHub.