ipfs/kubo · critical

panic(err)

Error message

panic(err)

What it means

`FormatKeyID` panics when it cannot render a peer ID's CID form in base36. Peer IDs are internally converted to an identity-multihash CID; `peer.ToCid(id).StringOfBase(mbase.Base36)` can only fail for multibase/multihash encoding errors, which for valid peer IDs should be impossible — so the helper treats failure as a programming bug and panics rather than returning an error.

Source

Thrown at core/coreiface/idfmt.go:10

package iface

import (
	"github.com/libp2p/go-libp2p/core/peer"
	mbase "github.com/multiformats/go-multibase"
)

func FormatKeyID(id peer.ID) string {
	if s, err := peer.ToCid(id).StringOfBase(mbase.Base36); err != nil {
		panic(err)
	} else {
		return s
	}
}

// FormatKey formats the given IPNS key in a canonical way.
func FormatKey(key Key) string {
	return FormatKeyID(key.ID())
}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Ensure the peer.ID comes from a trusted source (parsed via peer.Decode or returned by libp2p APIs) before passing it to FormatKeyID/FormatKey.
  2. If you cannot guarantee validity, wrap the call with recover() or validate the ID by round-tripping peer.ToCid(id).String() first and checking the error.
  3. In library code you control, prefer a non-panicking variant that returns the error from StringOfBase instead of panicking.

Example fix

// before
s := iface.FormatKeyID(id) // panics on invalid id
// after
func safeFormatKeyID(id peer.ID) (s string, err error) {
    defer func() { if r := recover(); r != nil { err = fmt.Errorf("invalid peer id: %v", r) } }()
    return iface.FormatKeyID(id), nil
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the peer ID before formatting:
if _, err := peer.ToCid(id).String(); err != nil {
    return fmt.Errorf("invalid peer id: %w", err)
}

Type guard

func validPeerID(id peer.ID) bool {
    _, err := peer.ToCid(id).StringOfBase(mbase.Base36)
    return err == nil
}

Try / catch

func formatKeyIDSafe(id peer.ID) (s string, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("FormatKeyID panicked: %v", r)
        }
    }()
    return iface.FormatKeyID(id), nil
}

Prevention

When it happens

Trigger: Calling `FormatKeyID` (directly or via `FormatKey`) with a peer.ID that fails CID conversion or base36 encoding — in practice only reachable with a corrupt/invalid peer.ID value (e.g. an incorrectly deserialized or hand-crafted ID whose multihash cannot be encoded).

Common situations: Embedding kubo/coreiface and constructing peer.ID values from raw bytes that are not valid multihashes; decoding bugs where a key ID string was corrupted before being parsed back into a peer.ID; fuzzing or tests exercising invalid peer ID shapes.

Related errors


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