ipfs/kubo · error
failed to derive PeerID from PrivKey: %w
Error message
failed to derive PeerID from PrivKey: %w
What it means
After decoding PrivKey into a crypto private key, nodePeerID derives the libp2p PeerID with peer.IDFromPrivateKey. This wraps a failure of that derivation — the decoded key bytes are not usable to compute the corresponding PeerID (malformed key structure despite passing base64 decode). Rare, since decode and derivation usually fail together.
Source
Thrown at core/commands/config.go:643
// config. Identity.PeerID must equal this value; the node refuses to start
// when the two disagree.
func nodePeerID(r repo.Repo) (peer.ID, error) {
keyF, err := getConfig(r, config.PrivKeySelector)
if err != nil {
return "", errors.New("failed to get PrivKey")
}
pkstr, ok := keyF.Value.(string)
if !ok {
return "", errors.New("private key in config was not a string")
}
ident := config.Identity{PrivKey: pkstr}
pk, err := ident.DecodePrivateKey("")
if err != nil {
return "", fmt.Errorf("failed to decode PrivKey: %w", err)
}
id, err := peer.IDFromPrivateKey(pk)
if err != nil {
return "", fmt.Errorf("failed to derive PeerID from PrivKey: %w", err)
}
return id, nil
}
func replaceConfig(r repo.Repo, file io.Reader) error {
var newCfg config.Config
if err := json.NewDecoder(file).Decode(&newCfg); err != nil {
return errors.New("failed to decode file as config")
}
// Handle Identity.PrivKey (secret)
if len(newCfg.Identity.PrivKey) != 0 {
return errors.New("setting private key with API is not supported")
}
keyF, err := getConfig(r, config.PrivKeySelector)
if err != nil {View on GitHub (pinned to 329838acdf)
Solutions
- Replace the key with a known-good one: re-copy Identity.PrivKey from a backup of the original config
- Regenerate the identity: `ipfs init` in a fresh directory and migrate pins/data, accepting the PeerID change
- Verify the key round-trips in a scratch repo: set it there and run `ipfs id`; if that fails, the key material itself is corrupt
- Check the underlying wrapped error (%w) for the specific crypto failure to confirm it's the key, not the repo
Example fix
// before: corrupted key from a lossy transfer "PrivKey": "CAESqA…(truncated)…" // after: exact base64 string from backup "PrivKey": "CAESqA...==" # copied byte-for-byte
Defensive patterns
Strategy: retry
Validate before calling
# verify the key works in a scratch repo before trusting it ipfs init /tmp/scratch-repo && IPFS_PATH=/tmp/scratch-repo ipfs config --json Identity.PrivKey "$(jq -r .Identity.PrivKey config.json)"
Try / catch
id, err := peer.IDFromPrivateKey(pk)
if err != nil {
return fmt.Errorf("decoded PrivKey cannot yield a PeerID (restore key from backup): %w", err)
} Prevention
- Restore Identity.PrivKey from a known-good backup rather than repairing corrupted material
- Round-trip test the key in a scratch repo (`ipfs id`) before deploying it to production configs
- Avoid merging config fragments from different repos — take Identity wholesale from one source
- Note PeerID changes if you regenerate; plan pin/data migration accordingly
When it happens
Trigger: A PrivKey string that base64-decodes and unmarshals but yields a key with invalid/missing public component; corrupted key material; keys of types whose PeerID derivation fails in the linked libp2p version.
Common situations: Configs assembled by merging fragments from different repos; keys altered by lossy text processing (charset conversion, line-wrapping corruption) that base64 still happens to accept.
Related errors
- unrecognized key type: %s
- cannot set Identity.PeerID to a value that does not match th
- failed to get PrivKey
- failed to decode PrivKey: %w
- decoding old private key (%v)
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/81808802bdc55928.
Report an issue: GitHub.