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
- Ensure the peer.ID comes from a trusted source (parsed via peer.Decode or returned by libp2p APIs) before passing it to FormatKeyID/FormatKey.
- 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.
- 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
- Only pass peer.ID values from trusted libp2p APIs (peer.Decode, peer.ID(s))
- Round-trip validate IDs parsed from external input before formatting
- Wrap panic-prone formatters with recover() at library boundaries
- Add tests covering malformed peer ID inputs if you handle user-supplied keys
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
- invalid IPNS name: %w
- cannot create new key: %w
- this action must be run in online mode, try running 'ipfs da
- could not resolve name
- Name.Resolve: depth other than 1 or %d not supported
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/6782be926aa21c00.
Report an issue: GitHub.