ipfs/kubo · error
BUG: unhandled autonat service mode
Error message
BUG: unhandled autonat service mode
What it means
AutoNAT.ServiceMode is validated against known values (Disabled, Unset, Enabled) when building the libp2p node; the switch intentionally panics for anything else because config validation should have rejected unknown values earlier. Reaching this panic indicates a genuine code/config-layer bug, not user error.
Source
Thrown at core/node/groups.go:99
pubsubOptions = append(pubsubOptions, pubsub.WithSeenMessagesStrategy(seenMessagesStrategy))
switch cfg.Pubsub.Router {
case "":
fallthrough
case "gossipsub":
ps = fx.Provide(libp2p.GossipSub(pubsubOptions...))
case "floodsub":
ps = fx.Provide(libp2p.FloodSub(pubsubOptions...))
default:
return fx.Error(fmt.Errorf("unknown pubsub router %s", cfg.Pubsub.Router))
}
}
autonat := fx.Options()
switch cfg.AutoNAT.ServiceMode {
default:
panic("BUG: unhandled autonat service mode")
case config.AutoNATServiceDisabled:
case config.AutoNATServiceUnset:
// TODO
//
// We're enabling the AutoNAT service by default on _all_ nodes
// for the moment.
//
// We should consider disabling it by default if the dht is set
// to dhtclient.
fallthrough
case config.AutoNATServiceEnabled:
autonat = fx.Provide(libp2p.AutoNATService(cfg.AutoNAT.Throttle, false))
case config.AutoNATServiceEnabledV1Only:
autonat = fx.Provide(libp2p.AutoNATService(cfg.AutoNAT.Throttle, true))
}
enableTCPTransport := cfg.Swarm.Transports.Network.TCP.WithDefault(true)
enableWebsocketTransport := cfg.Swarm.Transports.Network.Websocket.WithDefault(true)View on GitHub (pinned to 329838acdf)
Solutions
- Report a bug at https://github.com/ipfs/kubo/issues with the config's AutoNAT.ServiceMode value and Kubo version
- Inspect `ipfs config AutoNAT.ServiceMode` and set it to "enabled" or "disabled" to work around the panic
- Update/rollback to a released Kubo version where the switch covers the config value
Example fix
// before (groups.go)
switch cfg.AutoNAT.ServiceMode {
default:
panic("BUG: unhandled autonat service mode")
case config.AutoNATServiceDisabled:
// after (add the missing case)
switch cfg.AutoNAT.ServiceMode {
default:
panic("BUG: unhandled autonat service mode")
case config.AutoNATServiceDisabled:
case config.AutoNATServiceNewMode: // newly added enum value
// handle new mode
Defensive patterns
Strategy: validation
Validate before calling
// Ensure AutoNAT.ServiceMode is a known value before constructing the node
switch cfg.AutoNAT.ServiceMode {
case "", "disabled", "enabled", "enable" /* per version constants */:
// ok
default:
return fmt.Errorf("AutoNAT.ServiceMode %q unknown", cfg.AutoNAT.ServiceMode)
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Errorf("node construction panicked: %v", r)
}
}() Prevention
- Keep config package enum constants and the LibP2P switch in sync when adding modes
- Set AutoNAT.ServiceMode only via documented CLI values
- Report panics with the exact config value and Kubo version
When it happens
Trigger: `cfg.AutoNAT.ServiceMode` holds a value that passed earlier parsing but is not one of the enumerated cases — a bug in config deserialization or a new enum value added without updating this switch.
Common situations: A dev build or patched Kubo where a new AutoNATService constant was added but the LibP2P switch in core/node/groups.go was not updated; corrupted config producing an unexpected intermediate value.
Related errors
- serveHTTPGatewayOverLibp2p: ConstructNode() failed: %s
- unknown autonat mode: %s
- internal error during CAR export
- internal error encoding node
- invalid peer id
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/da6f1ad69952776b.
Report an issue: GitHub.