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

  1. Restore the original PrivKey from backup or regenerate: `ipfs init` in a fresh repo and copy the whole Identity block verbatim
  2. Use `ipfs key export <name>` to get the canonical base64 format and paste it exactly, without whitespace
  3. Verify the string is valid base64: `echo <key> | base64 -d > /dev/null && echo ok`
  4. 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

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

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/89587867abb1d881. Report an issue: GitHub.