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

  1. Report a bug at https://github.com/ipfs/kubo/issues with the config's AutoNAT.ServiceMode value and Kubo version
  2. Inspect `ipfs config AutoNAT.ServiceMode` and set it to "enabled" or "disabled" to work around the panic
  3. 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

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


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