ipfs/kubo · error
missing private key for node ID: %s
Error message
missing private key for node ID: %s
What it means
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.
Source
Thrown at core/node/libp2p/hostopt.go:20
import (
"fmt"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/peerstore"
)
type HostOption func(id peer.ID, ps peerstore.Peerstore, options ...libp2p.Option) (host.Host, error)
var DefaultHostOption HostOption = constructPeerHost
// isolates the complex initialization steps
func constructPeerHost(id peer.ID, ps peerstore.Peerstore, options ...libp2p.Option) (host.Host, error) {
pkey := ps.PrivKey(id)
if pkey == nil {
return nil, fmt.Errorf("missing private key for node ID: %s", id)
}
options = append([]libp2p.Option{libp2p.Identity(pkey), libp2p.Peerstore(ps)}, options...)
return libp2p.New(options...)
}
View on GitHub (pinned to 329838acdf)
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
Example fix
// before h, err := constructPeerHost(id, peerstore.NewPeerstore()) // after ps := peerstore.NewPeerstore() ps.AddPrivKey(id, sk) h, err := constructPeerHost(id, ps)
Defensive patterns
Strategy: type-guard
Validate before calling
if ps.PrivKey(id) == nil {
return fmt.Errorf("peerstore missing private key for %s; add via ps.AddPrivKey(id, sk) or libp2p.Identity(sk)", id)
} Type guard
func hasIdentityKey(ps peerstore.Peerstore, id peer.ID) bool { return ps.PrivKey(id) != nil } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- serveHTTPGatewayOverLibp2p: ConstructNode() failed: %s
- unrecognized key type: %s
- cannot set Identity.PeerID to a value that does not match th
- failed to get PrivKey
- private key in config was not a string
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/81a1b8135e723cd4.
Report an issue: GitHub.