{"record":{"id":"e3445ac44aa0d328","repo":"ipfs/kubo","slug":"failed-to-get-privkey","errorCode":null,"errorMessage":"failed to get PrivKey","messagePattern":"failed to get PrivKey","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/config.go","lineNumber":630,"sourceCode":"\teditorAndArgs, err := parseEditorCommand(editor)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot parse $EDITOR value: %s\", err)\n\t}\n\teditor = editorAndArgs[0]\n\targs := append(editorAndArgs[1:], filename)\n\n\tcmd := exec.Command(editor, args...)\n\tcmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr\n\treturn cmd.Run()\n}\n\n// nodePeerID derives the PeerID implied by the private key stored in the repo\n// config. Identity.PeerID must equal this value; the node refuses to start\n// when the two disagree.\nfunc nodePeerID(r repo.Repo) (peer.ID, error) {\n\tkeyF, err := getConfig(r, config.PrivKeySelector)\n\tif err != nil {\n\t\treturn \"\", errors.New(\"failed to get PrivKey\")\n\t}\n\tpkstr, ok := keyF.Value.(string)\n\tif !ok {\n\t\treturn \"\", errors.New(\"private key in config was not a string\")\n\t}\n\tident := config.Identity{PrivKey: pkstr}\n\tpk, err := ident.DecodePrivateKey(\"\")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to decode PrivKey: %w\", err)\n\t}\n\tid, err := peer.IDFromPrivateKey(pk)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to derive PeerID from PrivKey: %w\", err)\n\t}\n\treturn id, nil\n}\n\nfunc replaceConfig(r repo.Repo, file io.Reader) error {","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/config.go#L612-L648","documentation":"`nodePeerID` derives the PeerID from Identity.PrivKey in the repo config; it first calls getConfig(r, config.PrivKeySelector) to fetch the key. If that read fails for any reason (config unreadable, key missing), the specific cause is discarded and this generic message is returned. It is used by `ipfs id`-style flows and replaceConfig to validate the new config's key.","triggerScenarios":"Calling `ipfs config replace` with a file lacking Identity.PrivKey, or any code path invoking nodePeerID on a repo whose config cannot supply the PrivKey field (missing Identity section, unreadable config).","commonSituations":"Replacing the config with a trimmed/edited JSON file that dropped the identity block; a corrupt or hand-modified config where Identity.PrivKey was removed; permission problems reading the repo.","solutions":["Ensure the config contains Identity.PrivKey: check with `ipfs config show | jq '.Identity | has(\"PrivKey\")'`","Never strip the Identity section when editing or replacing config; keep the original config's Identity when using `ipfs config replace`","Restore the repo from backup or re-initialize (`ipfs init`) if the key is truly lost — a lost PrivKey means a lost PeerID","Check repo readability/permissions if the key exists but cannot be read"],"exampleFix":"// before: config replace with a file missing Identity\n{ \"Addresses\": { ... } }\n// after: merge new settings into the existing config so Identity.PrivKey is preserved\njq --slurpfile old <(ipfs config show) '.Identity = $old[0].Identity' new-config.json > merged.json\nipfs config replace merged.json","handlingStrategy":"validation","validationCode":"ipfs config show | jq -e '.Identity.PrivKey | type == \"string\" and length > 0' >/dev/null && echo \"PrivKey present\" || echo \"PrivKey missing — never strip Identity from config\"","typeGuard":null,"tryCatchPattern":"pid, err := nodePeerID(r)\nif err != nil {\n    if err.Error() == \"failed to get PrivKey\" {\n        return fmt.Errorf(\"Identity.PrivKey missing from config: %w\", err)\n    }\n    return err\n}","preventionTips":["When using `ipfs config replace`, merge new settings into the output of `ipfs config show` so Identity is preserved","Back up $IPFS_PATH/config.json (especially Identity) before any repo surgery","Never delete the Identity block when cleaning up configs","Check repo permissions if the key exists but reads fail"],"tags":["config","identity","peerid"],"backgroundTag":"privkey-missing","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"}