schollz/croc · error · Error
This browser cannot stream a file this large. Receive it wit
Error message
This browser cannot stream a file this large. Receive it with the croc CLI instead.
What it means
Thrown by chooseStoredReceiveDestination when the browser has neither showDirectoryPicker (File System Access API) nor streaming-download support (service workers + MessageChannel + secure context), and the largest offered file exceeds 256 MiB. Without streaming, the fallback DownloadDestination buffers the entire file in memory as a Blob, which the code refuses to do for large files.
Source
Thrown at web/src/protocol/storage.ts:379
) {
throw new DOMException("Destination selection cancelled", "AbortError");
}
return new DirectoryDestination(directory);
}
export async function chooseStoredReceiveDestination(offer: TransferOffer) {
if (window.showDirectoryPicker) {
return chooseReceiveDestination(offer);
}
if (supportsStreamingDownloadDestination()) {
return new StreamingDownloadDestination();
}
const largest = offer.files.reduce(
(maximum, file) => Math.max(maximum, file.size),
0,
);
if (largest > 256 * 1024 * 1024) {
throw new Error(
"This browser cannot stream a file this large. Receive it with the croc CLI instead.",
);
}
return new DownloadDestination();
}
export async function verifySink(sink: ReceiveSink, expected: Uint8Array) {
const actual = await sink.hash();
if (!bytesEqual(actual, expected)) {
throw new Error(
`The sender advertised xxhash ${hex(expected)}, but the received file hashes to ${hex(actual)}`,
);
}
}
export async function verifySinkSHA256(
sink: ReceiveSink,
expected: Uint8Array,View on GitHub (pinned to e25f1bdc04)
Solutions
- Receive with the croc CLI using the CLI token (formatStoredCLIToken) instead of the browser
- Serve the web app over HTTPS (or localhost) so supportsStreamingDownloadDestination() becomes true and streaming works
- Use a Chromium-based browser where showDirectoryPicker is available regardless of size
- Have the sender split the transfer into pieces under 256 MiB
Defensive patterns
Strategy: fallback
Validate before calling
import { supportsStreamingDownloadDestination, supportsDirectoryDestination } from "../protocol/storage";
const canBrowserReceive = (offer: TransferOffer): boolean =>
supportsDirectoryDestination() ||
supportsStreamingDownloadDestination() ||
offer.files.every((f) => f.size <= 256 * 1024 * 1024); Try / catch
try { return await chooseStoredReceiveDestination(offer); } catch (e) { if (e instanceof Error && e.message.includes("croc CLI")) { showUseCLIPrompt(share); return null; } throw e; } Prevention
- Check capability flags (serviceWorker, secure context, showDirectoryPicker) before offering browser receive for large files
- Always surface the croc CLI token alongside the browser link when files may exceed 256 MiB
When it happens
Trigger: offer.files max size > 256*1024*1024 AND window.showDirectoryPicker is undefined AND supportsStreamingDownloadDestination() is false (no serviceWorker, no MessageChannel, or insecure context on a non-localhost host).
Common situations: Firefox or Safari receiving a >256 MiB stored transfer; any browser serving the app over plain HTTP from a LAN IP or hostname (not a secure context, so no service worker registration); private-mode windows where service workers are disabled. The remedy is literally in the message: use the croc CLI receiver.
Related errors
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/4e92eed0c6d00a58.
Report an issue: GitHub.