JuliusBrussee/caveman · error
binary download failed: ${error.message}
Error message
binary download failed: ${error.message} What it means
asset() in the binary installer wraps fetch() with AbortSignal.timeout; any thrown error (DNS failure, connection refused, TLS problem, or the abort timeout firing) is rethrown as 'binary download failed: <cause>'. The message preserves the underlying error text for diagnosis.
Source
Thrown at packages/shared/binary-installer/installer.mjs:92
export function binaryInstallFilename(name, os = process.platform) {
return os === "win32" ? `${name}.exe` : name;
}
function timeoutMs() {
const raw = process.env.CAVE_SETUP_TIMEOUT ?? "300";
const seconds = Number(raw);
if (!Number.isInteger(seconds) || seconds <= 0) {
throw new Error(`CAVE_SETUP_TIMEOUT must be a positive integer (got ${JSON.stringify(raw)})`);
}
return seconds * 1000;
}
async function asset(url, timeout) {
let response;
try {
response = await fetch(url, { signal: AbortSignal.timeout(timeout) });
} catch (error) {
throw new Error(`binary download failed: ${error.message}`);
}
if (!response.ok) throw new Error(`binary download failed: HTTP ${response.status}`);
return response;
}
function signedDigest(checksums, bundleRaw) {
try {
const bundle = JSON.parse(bundleRaw);
if (bundle.mediaType !== "application/vnd.dev.sigstore.bundle.v0.3+json") return false;
if (bundle.messageSignature?.messageDigest?.algorithm !== "SHA2_256") return false;
const digest = createHash("sha256").update(checksums).digest();
const bundled = Buffer.from(bundle.messageSignature.messageDigest.digest, "base64");
if (digest.length !== bundled.length || !digest.equals(bundled)) return false;
return verify(
"sha256",
Buffer.from(checksums),
createPublicKey(BINARY_SIGNING_PUBKEY),
Buffer.from(bundle.messageSignature.signature, "base64"),View on GitHub (pinned to 27d5a3981a)
Solutions
- If the message mentions abort or timeout, raise CAVE_SETUP_TIMEOUT (for example 600) and retry
- Verify network reachability of the release base URL from that machine (curl the same URL)
- For proxies, configure one that global fetch honors (undici EnvHttpProxyAgent or NODE_USE_ENV_PROXY=1), or run the install where egress is open
- Pre-install the binary on a connected machine and point CAVEMAN_MCP_BIN / CAVEMAN_SHRINK_BIN / CAVEMAN_BROWSE_BIN at it
Example fix
# before CAVE_SETUP_TIMEOUT=30 npm run setup # 'binary download failed: TimeoutError: The operation was aborted' # after CAVE_SETUP_TIMEOUT=600 npm run setup
Defensive patterns
Strategy: retry
Validate before calling
// probe reachability before setup
await fetch(releaseBase, { signal: AbortSignal.timeout(5000) })
.catch(() => { throw new Error("release host unreachable — check egress/proxy"); }); Try / catch
for (const wait of [0, 2000, 8000]) {
await sleep(wait);
try { return await ensureBinary({ name, envVar }); }
catch (e) {
if (!/^binary download failed: /.test(String(e?.message)) || /HTTP \d+/.test(e.message)) throw e;
}
}
// retry transport failures only; HTTP-status failures are not retried blindly Prevention
- Pre-provision binaries in CI images and point CAVEMAN_*_BIN at them
- Size CAVE_SETUP_TIMEOUT to your link speed
- Ensure global fetch honors your proxy in Node (undici EnvHttpProxyAgent or NODE_USE_ENV_PROXY=1)
When it happens
Trigger: Offline machine, blocked DNS, firewall or egress rules denying the release host, a corporate proxy not honored by undici fetch, or a slow link exceeding CAVE_SETUP_TIMEOUT (abort/TimeoutError appears in the message).
Common situations: CI runners without internet egress; air-gapped environments; HTTPS_PROXY set but undici ignoring it; slow links timing out at the default 300 seconds.
Related errors
- binary download failed: HTTP ${response.status}
- binary download failed: response body missing
- signature check failed for ${artifact} — partial download de
- registration failed: HTTP ${response.status}
- caveman agent: tool timeoutMs must be a positive integer
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/aecd62c308c613e4.
Report an issue: GitHub.