ruvnet/ruflo · error · Error

Local IPFS upload failed: ${response.status} ${error}

Error message

Local IPFS upload failed: ${response.status} ${error}

What it means

The local-IPFS path POSTs to `${apiUrl}/api/v0/add` where apiUrl = process.env.IPFS_API_URL || 'http://localhost:5001' — i.e. the Kubo RPC API of your own node. This error means the node answered HTTP but returned a non-ok status; it is not a connection-refused error (a down node makes fetch itself reject with TypeError instead). Common causes: the daemon is running but the repo is locked (another ipfs daemon instance), the API is bound read-only, or the add request is malformed for that node.

Source

Thrown at v3/@claude-flow/cli/src/transfer/ipfs/upload.ts:446

  const body = Buffer.concat([
    Buffer.from(`--${boundary}\r\n`),
    Buffer.from(`Content-Disposition: form-data; name="file"; filename="${name}"\r\n`),
    Buffer.from(`Content-Type: application/json\r\n\r\n`),
    content,
    Buffer.from(`\r\n--${boundary}--\r\n`),
  ]);

  const response = await fetch(`${apiUrl}/api/v0/add?pin=${options.pin !== false}`, {
    method: 'POST',
    headers: {
      'Content-Type': `multipart/form-data; boundary=${boundary}`,
    },
    body,
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`Local IPFS upload failed: ${response.status} ${error}`);
  }

  const result = await response.json() as { Hash: string; Size: string; Name: string };
  const cid = result.Hash;

  // Try to get external gateway URL if configured
  const gatewayUrl = process.env.IPFS_GATEWAY_URL || options.gateway || 'https://ipfs.io';

  console.log(`[IPFS] Upload complete!`);
  console.log(`[IPFS] CID: ${cid}`);

  return {
    cid,
    size: content.length,
    gateway: gatewayUrl,
    pinnedAt: options.pin !== false ? new Date().toISOString() : undefined,
    url: `${gatewayUrl}/ipfs/${cid}`,
  };

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Confirm the node is healthy: curl http://localhost:5001/api/v0/id (or ipfs id) — if that also errors, fix the daemon first
  2. If the repo is locked, remove the stale lock: kill stray ipfs processes, then delete <ipfs repo>/repo.lock and restart ipfs daemon
  3. Point IPFS_API_URL at the RPC API (default http://localhost:5001), not the gateway port 8080
  4. For persistent failures, fall back to a pinning provider (web3.storage/pinata)

Example fix

# before
IPFS_API_URL=http://localhost:8080 npx claude-flow hooks transfer store --provider local
# gateway port answers the RPC route with an error -> Local IPFS upload failed: 404 ...

# after
ipfs daemon &  # ensure single healthy daemon
export IPFS_API_URL=http://localhost:5001
curl -s http://localhost:5001/api/v0/id  # sanity check before upload
Defensive patterns

Strategy: retry

Validate before calling

// Preflight: the Kubo RPC API must answer /api/v0/id before uploading
const apiUrl = process.env.IPFS_API_URL || 'http://localhost:5001';
const probe = await fetch(`${apiUrl}/api/v0/id`, { method: 'POST' });
if (!probe.ok) {
  throw new Error(`Local IPFS node unhealthy (${apiUrl}): ${probe.status} — start/repair 'ipfs daemon' before upload`);
}
await uploadToIPFS(content, { provider: 'local' });

Try / catch

try {
  result = await uploadToIPFS(content, { provider: 'local' });
} catch (e) {
  if (!/Local IPFS upload failed/.test(String((e as Error)?.message))) throw e;
  // node answered HTTP but errored: fix daemon (repo lock, wrong port) then retry once
  await new Promise(r => setTimeout(r, 1_000));
  result = await uploadToIPFS(content, { provider: 'local' });
}

Prevention

When it happens

Trigger: Uploading with provider 'local'/custom while two ipfs daemon processes fight over the same repo (repo lock -> 500); IPFS_API_URL pointing at a gateway port (8080) or read-only API instead of the RPC port 5001; a proxy in front of the API rejecting the multipart POST; node version whose /api/v0/add requires different params.

Common situations: 'ipfs daemon run twice' (stale lock from a crashed daemon); port confusion between Gateway (8080) and API (5001); remote nodes secured behind auth proxies; dockerized ipfs where the API is not exposed.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/90042a0e4ffe40c4. Report an issue: GitHub.