schollz/croc · error
Storage service returned an invalid remaining-download count
Error message
Storage service returned an invalid remaining-download count
What it means
Thrown after a successful chunk download: the X-Croc-Downloads-Remaining response header is present but is not a non-negative safe integer. The header reports how many downloads remain before deletion; a missing header is treated as 0, but a present-and-malformed value (empty, 'abc', '-1', '1.5') is a protocol violation.
Source
Thrown at web/src/protocol/stored.ts:886
if (
(error instanceof DOMException && error.name === "AbortError") ||
(error instanceof StoredHTTPError && error.status < 500)
) {
throw error;
}
await new Promise((resolve) =>
window.setTimeout(resolve, (attempt + 1) * 250),
);
}
}
if (!response) throw lastError;
forgetClaim(inspection.share.id);
forgetVerifiedDownload(inspection.share.id);
const header = response.headers.get("X-Croc-Downloads-Remaining");
if (header === null) return 0;
const remaining = Number(header);
if (!Number.isSafeInteger(remaining) || remaining < 0) {
throw new Error(
"Storage service returned an invalid remaining-download count",
);
}
return remaining;
}
export async function receiveStoredTransfer(options: {
inspection: StoredInspection;
settings: StoredSettings;
callbacks: ReceiveCallbacks;
signal?: AbortSignal;
}) {
const { inspection, settings, callbacks, signal } = options;
if (hasVerifiedDownload(inspection.share.id)) {
const session: StoredReceiveSession = {
inspection,
settings,View on GitHub (pinned to e25f1bdc04)
Solutions
- Reproduce with curl -i against the service to see the actual header value
- Fix or disable proxy header rewriting for this endpoint
- Upgrade the storage service so it always emits a valid integer header or omits it entirely
Defensive patterns
Strategy: try-catch
Type guard
function isValidRemainingHeader(v: string | null): boolean {
if (v === null) return true;
return /^\d+$/.test(v) && Number.isSafeInteger(Number(v));
} Try / catch
try { await commitStoredDownload(session); } catch (e) { if (e instanceof Error && e.message.includes('invalid remaining-download count')) { logHeaderDiagnostics(); markRemainingUnknown(); return; } throw e; } Prevention
- Ensure proxies pass X-Croc-Downloads-Remaining through untouched
- Treat this as a service/proxy defect; do not blind-retry the download
When it happens
Trigger: The download request succeeds but a reverse proxy, CDN, or the service emits a corrupted X-Croc-Downloads-Remaining header: present yet empty or non-numeric. headers.get() is case-insensitive, so the issue is always the value, not casing.
Common situations: nginx/Cloudflare rewriting or padding custom headers; a partially deployed service version that sets the header inconsistently across code paths.
Related errors
- Storage service returned unsupported chunk size ${created.ch
- Stored-transfer manifest is too large
- Storage service returned an invalid claim capability
- Transfer refused
- Relay returned an invalid port list: ${banner}
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/a326322630fc7e7c.
Report an issue: GitHub.