{"record":{"id":"e24612c74b09276e","repo":"ipfs/kubo","slug":"private-network-does-not-work-with-routing-type-au","errorCode":null,"errorMessage":"private network does not work with Routing.Type=auto. Update your config to Routing.Type=dht (or none, and do manual peering)","messagePattern":"private network does not work with Routing\\.Type=auto\\. Update your config to Routing\\.Type=dht \\(or none, and do manual peering\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/ipfs/kubo/daemon.go","lineNumber":962,"sourceCode":"\treturn errc, nil\n}\n\nfunc rewriteMaddrToUseLocalhostIfItsAny(maddr ma.Multiaddr) ma.Multiaddr {\n\tfirst, rest := ma.SplitFirst(maddr)\n\n\tswitch {\n\tcase first.Equal(&manet.IP4Unspecified[0]):\n\t\treturn manet.IP4Loopback.Encapsulate(rest)\n\tcase first.Equal(&manet.IP6Unspecified[0]):\n\t\treturn manet.IP6Loopback.Encapsulate(rest)\n\tdefault:\n\t\treturn maddr // not ip\n\t}\n}\n\nfunc validateDaemonConfig(cfg *config.Config, routingOption string, privateNetwork bool) error {\n\tif privateNetwork && (routingOption == routingOptionAutoKwd || routingOption == routingOptionAutoClientKwd) {\n\t\treturn errors.New(\"private network does not work with Routing.Type=auto. Update your config to Routing.Type=dht (or none, and do manual peering)\")\n\t}\n\n\t// Check for deprecated Provider/Reprovider configuration after migration.\n\t// This should never happen for regular users, but is useful error for people who have Docker orchestration\n\t// that blindly sets config keys (overriding automatic Kubo migration).\n\t//nolint:staticcheck // intentionally checking deprecated fields\n\tif cfg.Provider.Enabled != config.Default || !cfg.Provider.Strategy.IsDefault() || !cfg.Provider.WorkerCount.IsDefault() {\n\t\treturn errors.New(\"deprecated configuration detected. Manually migrate 'Provider' fields to 'Provide' and remove 'Provider' from your config. Documentation: https://github.com/ipfs/kubo/blob/master/docs/config.md#provide\")\n\t}\n\t//nolint:staticcheck // intentionally checking deprecated fields\n\tif !cfg.Reprovider.Interval.IsDefault() || !cfg.Reprovider.Strategy.IsDefault() {\n\t\treturn errors.New(\"deprecated configuration detected. Manually migrate 'Reprovider' fields to 'Provide': Reprovider.Strategy -> Provide.Strategy, Reprovider.Interval -> Provide.DHT.Interval. Remove 'Reprovider' from your config. Documentation: https://github.com/ipfs/kubo/blob/master/docs/config.md#provide\")\n\t}\n\tif cfg.Provide.Strategy.WithDefault(\"\") == \"flat\" {\n\t\treturn errors.New(\"Provide.Strategy='flat' is no longer supported. Use 'all' instead. Documentation: https://github.com/ipfs/kubo/blob/master/docs/config.md#providestrategy\")\n\t}\n\tif cfg.Experimental.StrategicProviding {\n\t\treturn errors.New(\"Experimental.StrategicProviding was removed. Remove it from your config. Documentation: https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#strategic-providing\")","sourceCodeStart":944,"sourceCodeEnd":980,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/cmd/ipfs/kubo/daemon.go#L944-L980","documentation":"validateDaemonConfig rejects daemon startup when Swarm.Key (private network) is combined with Routing.Type=auto or autoclient. Auto routing may use public DHT/client routers that bypass the private swarm, which is incompatible with private networks. The operator must pick an explicit routing mode.","triggerScenarios":"Running `ipfs daemon` in a private network (Swarm.Key set / LIBP2P_SWARM_KEY or --swarm-key) while config has Routing.Type=auto or Routing.Type=autoclient, or the CLI passes --routing=auto with a swarm key.","commonSituations":"Private/clusters deployments provisioned by Docker/K8s orchestration that blindly sets Routing.Type=auto; nodes migrated to auto routing after joining a permissioned network.","solutions":["Set explicit routing: `ipfs config Routing.Type dht` (full DHT inside the private network)","Or disable routing entirely: `ipfs config Routing.Type none` and use manual peering (`Peering.Peers`)","If CLI flag used, change `--routing=auto` to `--routing=dht` or `--routing=none`","Remove the swarm key if a private network was not intended"],"exampleFix":"// before\n$ ipfs config Routing.Type\nauto   # with Swarm.Key set\nError: private network does not work with Routing.Type=auto...\n\n// after\n$ ipfs config Routing.Type dht\n$ ipfs daemon","handlingStrategy":"validation","validationCode":"// reject invalid combo before launching daemon\ncfg=$(ipfs config Routing.Type); has_key=$(test -f \"$IPFS_PATH/swarm.key\" && echo yes)\nif [ \"$has_key\" = yes ] && { [ \"$cfg\" = auto ] || [ \"$cfg\" = autoclient ]; }; then echo \"private network requires Routing.Type=dht or none\"; fi","typeGuard":null,"tryCatchPattern":"if err := daemonFunc(...); err != nil {\n    if strings.Contains(err.Error(), \"private network does not work\") {\n        log.Fatalf(\"fix routing config: %v\", err)\n    }\n}","preventionTips":["Never combine swarm keys with Routing.Type=auto in provisioning templates","Pin explicit Routing.Type (dht|none) for private-network deployments","Audit Docker/K8s env writers that set Routing.* blindly","Test config with `ipfs config show` before rolling out to the fleet"],"tags":["config","routing","private-network","validation"],"backgroundTag":"incompatible-config-combination","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}