{"record":{"id":"81a1b8135e723cd4","repo":"ipfs/kubo","slug":"missing-private-key-for-node-id-s","errorCode":null,"errorMessage":"missing private key for node ID: %s","messagePattern":"missing private key for node ID: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/node/libp2p/hostopt.go","lineNumber":20,"sourceCode":"\nimport (\n\t\"fmt\"\n\n\t\"github.com/libp2p/go-libp2p\"\n\t\"github.com/libp2p/go-libp2p/core/host\"\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n\t\"github.com/libp2p/go-libp2p/core/peerstore\"\n)\n\ntype HostOption func(id peer.ID, ps peerstore.Peerstore, options ...libp2p.Option) (host.Host, error)\n\nvar DefaultHostOption HostOption = constructPeerHost\n\n// isolates the complex initialization steps\nfunc constructPeerHost(id peer.ID, ps peerstore.Peerstore, options ...libp2p.Option) (host.Host, error) {\n\tpkey := ps.PrivKey(id)\n\tif pkey == nil {\n\t\treturn nil, fmt.Errorf(\"missing private key for node ID: %s\", id)\n\t}\n\toptions = append([]libp2p.Option{libp2p.Identity(pkey), libp2p.Peerstore(ps)}, options...)\n\treturn libp2p.New(options...)\n}\n","sourceCodeStart":2,"sourceCodeEnd":25,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/node/libp2p/hostopt.go#L2-L25","documentation":"constructPeerHost builds the libp2p host and requires the node's private key to be present in the supplied peerstore. If ps.PrivKey(id) returns nil — the key was never added to the peerstore — host construction fails with this error naming the peer ID. It indicates the identity key was not loaded/injected into the peerstore before host construction.","triggerScenarios":"Calling constructPeerHost (DefaultHostOption) with a peerstore that lacks the entry for the given peer ID — e.g. an embedder building a host manually without adding the identity key via ps.AddPrivKey, or identity loading failing upstream in the fx graph.","commonSituations":"kubo-as-a-library embedders constructing a libp2p host with a fresh peerstore but forgetting libp2p.Identity or peerstore injection; identity config load errors that were swallowed upstream; test harnesses passing an empty peerstore.","solutions":["Ensure the private key is added to the peerstore before constructing the host: `ps.AddPrivKey(id, sk)` where sk is parsed from cfg.Identity.PrivKey","When using libp2p.New directly, pass libp2p.Identity(sk) so the host injects the key itself","In kubo, verify identity loading succeeded upstream (no prior errors about Identity.PrivKey) and that you are not constructing a host with an empty/temporary peerstore"],"exampleFix":"// before\nh, err := constructPeerHost(id, peerstore.NewPeerstore())\n// after\nps := peerstore.NewPeerstore()\nps.AddPrivKey(id, sk)\nh, err := constructPeerHost(id, ps)","handlingStrategy":"type-guard","validationCode":"if ps.PrivKey(id) == nil {\n    return fmt.Errorf(\"peerstore missing private key for %s; add via ps.AddPrivKey(id, sk) or libp2p.Identity(sk)\", id)\n}","typeGuard":"func hasIdentityKey(ps peerstore.Peerstore, id peer.ID) bool { return ps.PrivKey(id) != nil }","tryCatchPattern":null,"preventionTips":["Always pass libp2p.Identity(sk) when constructing hosts in embedders","Load the key from cfg.Identity.PrivKey and inject it into the peerstore before host construction","Check for upstream identity-load errors; do not proceed with a half-initialized identity"],"tags":["libp2p","identity","peerstore"],"backgroundTag":"missing-private-key","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"}