ipfs/kubo · error
failed to decode PrivKey: %w
Error message
failed to decode PrivKey: %w
What it means
nodePeerID decodes the base64 Identity.PrivKey string via config.Identity.DecodePrivateKey. This error wraps that decode failure: the string is present and a string, but not valid base64 protobuf-encoded private key bytes (or of an unsupported key type).
Source
Thrown at core/commands/config.go:639
return cmd.Run()
}
// nodePeerID derives the PeerID implied by the private key stored in the repo
// 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")View on GitHub (pinned to 329838acdf)
Solutions
- Restore the original PrivKey from backup or regenerate: `ipfs init` in a fresh repo and copy the whole Identity block verbatim
- Use `ipfs key export <name>` to get the canonical base64 format and paste it exactly, without whitespace
- Verify the string is valid base64: `echo <key> | base64 -d > /dev/null && echo ok`
- Never convert PEM/ssh keys into Identity.PrivKey; only libp2p protobuf-encoded base64 keys are accepted
Example fix
// before: PEM in config "PrivKey": "-----BEGIN PRIVATE KEY-----\n..." // after: base64 protobuf key as produced by kubo "PrivKey": "CAESqA...=="
Defensive patterns
Strategy: validation
Validate before calling
key=$(jq -r '.Identity.PrivKey' "$IPFS_PATH/config"); echo -n "$key" | base64 -d >/dev/null 2>&1 && echo "valid base64" || echo "PrivKey is not valid base64"
Try / catch
pk, err := ident.DecodePrivateKey("")
if err != nil {
return fmt.Errorf("Identity.PrivKey is corrupt or not a libp2p protobuf key: %w", err)
} Prevention
- Copy Identity.PrivKey byte-for-byte; avoid editors/scripts that wrap lines or alter encoding
- Only use keys from `ipfs key export` or a kubo-generated config — never PEM/ssh/hex keys
- Validate base64 before pasting: `echo <key> | base64 -d | head -c4 | xxd`
- Keep a backup of the original config before any key manipulation
When it happens
Trigger: PrivKey truncated or modified during copy/paste into config; key in the wrong format (raw PEM, hex, JSON-encoded libp2p key) instead of the base64 protobuf form kubo expects; whitespace/newlines injected by editors or scripts.
Common situations: Users moving configs between machines who hand-mangle the key; attempts to paste a key exported from another tool (openssl PEM, ssh key) directly into Identity.PrivKey; sed/regex edits corrupting the base64 payload.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unrecognized key type: %s
- decoding old private key (%v)
- 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/89587867abb1d881.
Report an issue: GitHub.