schollz/croc · error · Error
Received a file chunk outside the advertised file size
Error message
Received a file chunk outside the advertised file size
What it means
Thrown inside DataReceiver's chunk validation when a chunk fails structural checks: negative position, position not aligned to the 32 KiB CHUNK_SIZE grid, zero-length payload, payload larger than CHUNK_SIZE, or a position+length that exceeds the advertised file size from the sender's fileinfo. These invariants let the receiver write chunks directly at offsets without reassembly logic, so any violation aborts the transfer.
Source
Thrown at web/src/protocol/client.ts:624
private fail(error: Error) {
this.failure ??= error;
this.active?.reject(error);
this.active = undefined;
}
private accept(position: number, bytes: Uint8Array) {
const active = this.active;
if (!active) throw new Error("Received file data before it was requested");
active.queue = active.queue.then(async () => {
if (active.received.has(position)) throw new Error("Received a duplicate file chunk");
if (
position < 0 ||
position % CHUNK_SIZE !== 0 ||
bytes.byteLength === 0 ||
bytes.byteLength > CHUNK_SIZE ||
position + bytes.byteLength > active.file.size
) {
throw new Error("Received a file chunk outside the advertised file size");
}
active.received.add(position);
await active.sink.writeAt(position, bytes);
active.bytes += bytes.byteLength;
active.progress(active.bytes);
if (active.bytes === active.file.size) {
this.active = undefined;
active.resolve();
} else if (active.bytes > active.file.size) {
throw new Error("Received more data than the advertised file size");
}
});
active.queue.catch((error) => {
if (this.active === active) this.active = undefined;
active.reject(error instanceof Error ? error : new Error(String(error)));
});
return active.queue;
}View on GitHub (pinned to e25f1bdc04)
Solutions
- Keep CHUNK_SIZE identical on both peers — it is a wire-format constant, not a tunable
- Ensure files are not modified between prepareFiles and sendFileData; re-run prepareFiles if the underlying File changes
- Confirm the advertised size in senderInfo (s: file.size) matches what sendFileData actually slices
- When interoperating with croc CLI, verify its chunk size and framing match this client before mixing implementations
Defensive patterns
Strategy: validation
Validate before calling
// Before sending, assert chunk framing invariants the receiver will enforce
const CHUNK_SIZE = 32 * 1024;
function assertChunkOk(position: number, len: number, size: number) {
if (position < 0 || position % CHUNK_SIZE !== 0 || len === 0 || len > CHUNK_SIZE || position + len > size) {
throw new Error("Chunk framing violated before send");
}
} Type guard
function isAlignedPosition(position: number): boolean {
return Number.isSafeInteger(position) && position >= 0 && position % (32 * 1024) === 0;
} Try / catch
catch (e) {
if (e instanceof Error && e.message === "Received a file chunk outside the advertised file size") {
// framing/size mismatch between peers: restart transfer after aligning versions
}
throw e;
} Prevention
- Treat CHUNK_SIZE (32 KiB) as a wire constant — never change it on one peer only
- Ensure files are immutable between prepareFiles and sendFileData (snapshot files that may change)
- Verify the advertised size equals the streamed bytes in integration tests
When it happens
Trigger: Sender uses a different chunk size than 32768 (e.g. croc CLI default 1024*1024 or a changed constant); position encoding mismatch (endian or width); sender's advertised file size (s field) smaller than actual streamed bytes; file truncated on the sender side after prepareFiles hashed it; corruption that alters position or length bytes.
Common situations: CHUNK_SIZE constant changed on one peer but not the other; interoperating with the croc CLI whose chunking differs; sender's File object changes on disk between hashing (prepareFiles) and streaming (sendFileData) so slice() returns fewer/misaligned bytes; version drift in the framing format.
Related errors
- Received more data than the advertised file size
- Received an invalid file chunk
- Received a file position that is too large
- Received a duplicate file chunk
- Code must be at least 6 characters
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/04ef12db640223f6.
Report an issue: GitHub.