schollz/croc · error · Error
Received a file position that is too large
Error message
Received a file position that is too large
What it means
Thrown by DataReceiver.read when the 8-byte little-endian position prefix of a chunk exceeds Number.MAX_SAFE_INTEGER (2^53-1). Positions must map to safe JavaScript numbers for offset math, so a larger value cannot be a legitimate file offset (it would imply an exabyte-scale file). It indicates a corrupted frame or a hostile/buggy sender.
Source
Thrown at web/src/protocol/client.ts:593
this.fail(new Error("Data receiver stopped"));
}
private async read(socket: CrocSocket) {
const engine = wasm();
while (!this.stopped) {
try {
let payload = await engine.decrypt(await socket.receive(), this.key);
if (!this.noCompress) {
payload = await engine.decompress(payload, MAX_DECOMPRESSED_CHUNK_SIZE);
}
if (payload.byteLength < 9) throw new Error("Received an invalid file chunk");
const positionBig = new DataView(
payload.buffer,
payload.byteOffset,
payload.byteLength,
).getBigUint64(0, true);
if (positionBig > BigInt(Number.MAX_SAFE_INTEGER)) {
throw new Error("Received a file position that is too large");
}
const position = Number(positionBig);
const bytes = payload.slice(8);
await this.accept(position, bytes);
} catch (error) {
if (this.stopped) return;
this.stopped = true;
this.fail(error instanceof Error ? error : new Error(String(error)));
}
}
}
private fail(error: Error) {
this.failure ??= error;
this.active?.reject(error);
this.active = undefined;
}
View on GitHub (pinned to e25f1bdc04)
Solutions
- Reproduce with the same file and code phrase to distinguish transient corruption from deterministic encoding bugs
- Verify sender and recipient wasm builds match (same engine for setBigUint64 little-endian framing)
- Run the transfer over a different relay/network to rule out path corruption
- If interoperating with external clients, confirm they use the same 8-byte LE position framing
Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isSafeInteger(file.size) || file.size > Number.MAX_SAFE_INTEGER) {
throw new Error(`File too large to transfer: ${file.name}`);
} Type guard
function isSafeChunkPosition(positionBig: bigint): boolean {
return positionBig >= 0n && positionBig <= BigInt(Number.MAX_SAFE_INTEGER);
} Try / catch
catch (e) {
if (e instanceof Error && e.message === "Received a file position that is too large") {
// corrupted or hostile chunk: abort transfer, do not retry the same session
}
throw e;
} Prevention
- Reject files above Number.MAX_SAFE_INTEGER bytes before starting (prepareFiles already errors on unsafe sizes)
- Keep the position encoding identical on both peers: 64-bit little-endian BigUint64
- Treat oversized-position errors as corruption signals and restart with a fresh code phrase
When it happens
Trigger: Corrupted plaintext after decrypt/decompress where the first 8 bytes decode to a huge uint64; sender writes an unaligned or wrong-endian position; malicious peer deliberately crafting positions above 2^53; decompression bomb or misinterpretation of a non-chunk payload as a chunk.
Common situations: Wasm compress/decompress skew between peer builds; wrong decryption key producing plausible-length garbage; fuzzing or adversarial testing of the data channel; a modified sender that changes the position encoding.
Related errors
- Received an invalid file chunk
- Received a duplicate file chunk
- Received a file chunk outside the advertised file size
- Received more data than the advertised file size
- Received file data before it was requested
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/449bb45fff5354cf.
Report an issue: GitHub.