{"record":{"id":"d19993baba684158","repo":"ipfs/kubo","slug":"could-not-read-config-w","errorCode":null,"errorMessage":"could not read config: %w","messagePattern":"could not read config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/ipfs/kubo/daemon.go","lineNumber":1190,"sourceCode":"\n\tgo func() {\n\t\twg.Wait()\n\t\tclose(errc)\n\t}()\n\n\treturn errc, nil\n}\n\nconst gatewayProtocolID protocol.ID = \"/ipfs/gateway\" // FIXME: specify https://github.com/ipfs/specs/issues/433\n\nfunc serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error) {\n\tnode, err := cctx.ConstructNode()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"serveHTTPGatewayOverLibp2p: ConstructNode() failed: %s\", err)\n\t}\n\tcfg, err := node.Repo.Config()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not read config: %w\", err)\n\t}\n\n\tif !cfg.Experimental.GatewayOverLibp2p {\n\t\terrCh := make(chan error)\n\t\tclose(errCh)\n\t\treturn errCh, nil\n\t}\n\n\topts := []corehttp.ServeOption{\n\t\tcorehttp.MetricsCollectionOption(\"libp2p-gateway\"),\n\t\tcorehttp.Libp2pGatewayOption(),\n\t\tcorehttp.VersionOption(),\n\t}\n\n\thandler, err := corehttp.MakeHandler(node, nil, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":1172,"sourceCodeEnd":1208,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/cmd/ipfs/kubo/daemon.go#L1172-L1208","documentation":"After constructing the node, serveTrustlessGatewayOverLibp2p reads the repo config via node.Repo.Config() to check Experimental.GatewayOverLibp2p. Failure reading the config aborts startup with \"could not read config\". Unlike the CLI-level GetConfig, this reads the config from the already-open repo.","triggerScenarios":"node.Repo.Config() errors: config file deleted/renamed after repo open, unreadable due to permissions, or a repo-level read error (datastore/config layer).","commonSituations":"Config file removed while the daemon is starting; another process rewrote/locked the file; permission change mid-run; a plugin or supervisor replacing $IPFS_PATH between init and read.","solutions":["Restore $IPFS_PATH/config (from backup or re-create with `ipfs init` defaults, preserving Identity keys).","Fix permissions so the daemon user can read the file.","Do not delete or move the config while the daemon is starting; stop the daemon before editing.","Check the wrapped inner error for the exact filesystem cause (ENOENT vs EACCES)."],"exampleFix":"// before\n$ rm $IPFS_PATH/config  # daemon later fails\n// after\n$ ipfs shutdown  # edit only when stopped\n$ ipfs config show > config.bak  # keep a backup","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(filepath.Join(ipfsPath, \"config\")); err != nil {\n    return fmt.Errorf(\"config missing before daemon start: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"could not read config\") {\n    log.Fatalf(\"restore $IPFS_PATH/config (backup or ipfs init): %v\", err)\n}","preventionTips":["Never delete or move the config while the daemon is running.","Keep config backups alongside Identity keys.","Stop the daemon before scripted config changes.","Watch file permissions on $IPFS_PATH/config after deployments."],"tags":["config","repo","gateway","startup"],"backgroundTag":"config-load-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"}