{"record":{"id":"cbafe4b22470600a","repo":"ipfs/kubo","slug":"servehttpapi-setapiaddr-failed-w","errorCode":null,"errorMessage":"serveHTTPApi: SetAPIAddr() failed: %w","messagePattern":"serveHTTPApi: SetAPIAddr\\(\\) failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/ipfs/kubo/daemon.go","lineNumber":935,"sourceCode":"\t\t\treadyChannels[i] = make(chan struct{})\n\t\t\tready := readyChannels[i]\n\t\t\twg.Go(func() {\n\t\t\t\terrc <- corehttp.ServeWithReady(node, manet.NetListener(lis), ready, opts...)\n\t\t\t})\n\t\t}\n\n\t\t// Wait for all listeners to be ready or any to fail\n\t\tfor _, ready := range readyChannels {\n\t\t\tselect {\n\t\t\tcase <-ready:\n\t\t\t\t// This listener is ready\n\t\t\tcase err := <-errc:\n\t\t\t\treturn nil, fmt.Errorf(\"serveHTTPApi: %w\", err)\n\t\t\t}\n\t\t}\n\n\t\tif err := node.Repo.SetAPIAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr())); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"serveHTTPApi: SetAPIAddr() failed: %w\", err)\n\t\t}\n\t}\n\n\tgo func() {\n\t\twg.Wait()\n\t\tclose(errc)\n\t}()\n\n\treturn errc, nil\n}\n\nfunc rewriteMaddrToUseLocalhostIfItsAny(maddr ma.Multiaddr) ma.Multiaddr {\n\tfirst, rest := ma.SplitFirst(maddr)\n\n\tswitch {\n\tcase first.Equal(&manet.IP4Unspecified[0]):\n\t\treturn manet.IP4Loopback.Encapsulate(rest)\n\tcase first.Equal(&manet.IP6Unspecified[0]):","sourceCodeStart":917,"sourceCodeEnd":953,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/cmd/ipfs/kubo/daemon.go#L917-L953","documentation":"After API listeners are ready, serveHTTPApi writes the API multiaddr (with 0.0.0.0/:: rewritten to 127.0.0.1) into the repo via node.Repo.SetAPIAddr so clients can discover it. If persisting that address fails, the daemon aborts with this error. It signals a repo/datastore-level failure, not a network one.","triggerScenarios":"`ipfs daemon` starts listeners fine, but SetAPIAddr fails when writing the `api` file in the repo fails: read-only filesystem, full disk, permission denied on IPFS_PATH, or repo lock/datastore errors.","commonSituations":"IPFS_PATH on a mounted read-only volume or a crashed disk; running the daemon as a different user than `ipfs init` (permission denied); disk quota exceeded in containers.","solutions":["Check filesystem writability of IPFS_PATH: `touch $IPFS_PATH/testfile` and fix mount/permissions (`chown` to the daemon user)","Free disk space or raise container disk quota if the volume is full","Ensure the same user runs init and daemon; do not run as root against a user's repo","If the `api` file is corrupted, stop the daemon and delete `$IPFS_PATH/api` (it is regenerated)"],"exampleFix":"// before\n$ ls -ld ~/.ipfs\ndrwxr-xr-x 1 root root ~/.ipfs   # wrong owner\nError: serveHTTPApi: SetAPIAddr() failed: ... permission denied\n\n// after\n$ sudo chown -R ipfs:ipfs /data/ipfs\n$ IPFS_PATH=/data/ipfs ipfs daemon","handlingStrategy":"validation","validationCode":"// verify repo path is writable by the daemon user before start\nIPFS_PATH=/data/ipfs; test -w \"$IPFS_PATH\" && test -w \"$IPFS_PATH/datastore\" || echo \"IPFS_PATH not writable\"; df -h \"$IPFS_PATH\" | awk 'NR==2{if($5+0>95) print \"disk nearly full\"}'","typeGuard":null,"tryCatchPattern":"if err := daemonFunc(...); err != nil {\n    if strings.Contains(err.Error(), \"SetAPIAddr() failed\") {\n        log.Fatalf(\"repo write failure: %v\", err) // check fs perms/space\n    }\n}","preventionTips":["Run daemon under the same user that ran `ipfs init`","Monitor disk space/quota on the IPFS_PATH volume","Avoid read-only or ephemeral mounts for IPFS_PATH","Check ownership after container volume mounts (chown to daemon user)"],"tags":["daemon","filesystem","repo","permissions"],"backgroundTag":"repo-write-failed","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}