schollz/croc · error
Stored-transfer manifest is too large
Error message
Stored-transfer manifest is too large
What it means
Thrown when fetching a stored transfer's manifest: the ciphertext returned by GET /{share.id}/manifest exceeds maxManifestCiphertext (256 KiB, stored.ts:17). The manifest lists every file in the transfer; this guard stops the client from feeding an oversized (possibly malicious) payload into wasm storeOpenManifest, which would otherwise allocate proportionally.
Source
Thrown at web/src/protocol/stored.ts:673
senderMachineID: "encrypted temporary storage",
noCompress: true,
};
}
export async function inspectStoredTransfer(
share: StoredShare,
settings: StoredSettings,
signal?: AbortSignal,
) {
const redeem = await wasm().storeRedeemCapability(share.key);
const response = await authorizedFetch(
api(settings, `/${share.id}/manifest`),
base64URL(redeem),
{ signal },
);
const ciphertext = new Uint8Array(await response.arrayBuffer());
if (ciphertext.byteLength > maxManifestCiphertext) {
throw new Error("Stored-transfer manifest is too large");
}
const plaintext = await wasm().storeOpenManifest(
share.key,
share.id,
ciphertext,
settings.maxTransferBytes,
);
const manifest = JSON.parse(textDecoder.decode(plaintext)) as StoredManifest;
return {
share,
manifest,
offer: offerFromManifest(manifest),
expiresAt: response.headers.get("X-Croc-Expires-At") ?? undefined,
} satisfies StoredInspection;
}
function claimSessionKey(id: string) {
return `croc-store-claim:${id}`;View on GitHub (pinned to e25f1bdc04)
Solutions
- Reduce file count: zip/archive the directory and store the single archive
- Split into several smaller stored transfers
- If you fork/operate the client, review whether the 256 KiB cap suits your file counts
Example fix
# before
await uploadStoredFiles({ files: everyFileInNodeModules, settings });
# after
const bundle = await zipDirectory(nodeModulesDir);
await uploadStoredFiles({ files: [bundle], settings }); Defensive patterns
Strategy: validation
Validate before calling
// Rough manifest-size projection: ~130+ bytes per file entry after encryption overhead
const projected = files.reduce((n, f) => n + f.name.length + 128, 0);
if (projected > 200_000) throw new Error('too many files for one stored transfer; archive the directory first'); Try / catch
try { await inspectStoredTransfer(share, settings, signal); } catch (e) { if (e instanceof Error && e.message === 'Stored-transfer manifest is too large') { tellSenderToArchiveAndResend(); return; } throw e; } Prevention
- Archive large directory trees into one file before storing
- Keep stored transfers to a few thousand files or fewer
When it happens
Trigger: Inspecting/receiving a share whose encrypted manifest exceeds 256 KiB: transfers with an enormous number of files (each entry carries name, size, hash, mtime). Can also fire if the service returns a corrupted or attacker-controlled oversized body.
Common situations: Sharing directory trees like node_modules, photo archives, or build output with tens of thousands of files; a misbehaving storage endpoint returning junk.
Related errors
- Stored transfers can contain at most ${settings.maxFiles} fi
- Stored transfer exceeds the ${settings.maxTransferBytes} byt
- Storage service created ${acceptedDownloads} downloads inste
- Storage service returned an invalid claim capability
- Storage service returned an invalid remaining-download count
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/a44f8b92d6d626d5.
Report an issue: GitHub.