{"record":{"id":"0c14cadd722341d1","repo":"ipfs/kubo","slug":"invalid-dht-mode-q","errorCode":null,"errorMessage":"invalid DHT mode: %q","messagePattern":"invalid DHT mode: %q","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"routing/delegated.go","lineNumber":331,"sourceCode":"\tparams, ok := conf.Parameters.(*config.DHTRouterParams)\n\tif !ok {\n\t\treturn nil, errors.New(\"incorrect params for DHT router\")\n\t}\n\n\tif params.AcceleratedDHTClient {\n\t\treturn createFullRT(extra)\n\t}\n\n\tvar mode dht.ModeOpt\n\tswitch params.Mode {\n\tcase config.DHTModeAuto:\n\t\tmode = dht.ModeAuto\n\tcase config.DHTModeClient:\n\t\tmode = dht.ModeClient\n\tcase config.DHTModeServer:\n\t\tmode = dht.ModeServer\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid DHT mode: %q\", params.Mode)\n\t}\n\n\treturn createDHT(extra, params.PublicIPNetwork, mode)\n}\n\nfunc createDHT(params *ExtraDHTParams, public bool, mode dht.ModeOpt) (routing.Routing, error) {\n\tvar opts []dht.Option\n\n\tif public {\n\t\topts = append(opts, dht.QueryFilter(dht.PublicQueryFilter),\n\t\t\tdht.RoutingTableFilter(dht.PublicRoutingTableFilter),\n\t\t\tdht.RoutingTablePeerDiversityFilter(dht.NewRTPeerDiversityFilter(params.Host, 2, 3)))\n\t} else {\n\t\topts = append(opts, dht.ProtocolExtension(dual.LanExtension),\n\t\t\tdht.QueryFilter(dht.PrivateQueryFilter),\n\t\t\tdht.RoutingTableFilter(dht.PrivateRoutingTableFilter))\n\t}\n","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/routing/delegated.go#L313-L349","documentation":"This error comes from the delegated routing V2 router construction in kubo (routing/delegated.go). When building a DHT router from Routing.Type=\"dht\" configuration, dhtRoutingFromConfig maps the configured DHT.Mode string onto a go-libp2p-kad-dht mode option, accepting only \"auto\", \"client\", or \"server\". If params.Mode holds any other value, the switch falls through to the default branch and the router cannot be created, so it returns this error instead of a routing.Routing.","triggerScenarios":"Calling parse -> dhtRoutingFromConfig with a DHTRouterParams whose Mode field is set to something other than config.DHTModeAuto (\"auto\"), config.DHTModeClient (\"client\"), or config.DHTModeServer (\"server\") — e.g. Routing.Type is \"dht\" and Routing.DHT.Mode is a typo or an unsupported string.","commonSituations":"Typing the mode in the kubo config JSON (e.g. \"Mode\": \"dht\", \"Mode\": \"Server\", \"Mode\": \"client-mode\") instead of the exact lowercase \"client\", \"server\", or \"auto\"; generating the config from a script that writes an empty-but-present Mode value not matched by the case (empty string only passes if the code treats it as auto — any non-empty invalid string fails); migrating configs between versions where an old mode name is no longer recognized.","solutions":["Open the kubo config (config file or --json flag) and set Routing.DHT.Mode to exactly \"client\", \"server\", or \"auto\" (lowercase, e.g. `ipfs config --json Routing.DHT.Mode '\"client\"'`).","If you do not need a specific DHT role, remove the Mode key or set it to \"auto\" so kubo picks server/client based on reachability.","If the config is generated programmatically, compare against the exported constants config.DHTModeClient/DHTModeServer/DHTModeAuto rather than hand-written strings.","Check the daemon log/startup error for the %q value printed; fix that exact string in the configuration and restart."],"exampleFix":"// before (config JSON)\n\"Routing\": { \"Type\": \"dht\", \"DHT\": { \"Mode\": \"Client\" } }\n// after\n\"Routing\": { \"Type\": \"dht\", \"DHT\": { \"Mode\": \"client\" } }","handlingStrategy":"validation","validationCode":"mode := strings.ToLower(strings.TrimSpace(cfg.Routing.DHT.Mode))\nswitch config.DHTMode(mode) {\ncase \"\", config.DHTModeAuto, config.DHTModeClient, config.DHTModeServer:\n\t// valid\ndefault:\n\treturn fmt.Errorf(\"Routing.DHT.Mode %q invalid: must be auto, client, or server\", mode)\n}","typeGuard":"func validDHTMode(m config.DHTMode) bool {\n\tswitch m {\n\tcase \"\", config.DHTModeAuto, config.DHTModeClient, config.DHTModeServer:\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"r, err := parse(ctx, cfg)\nif err != nil {\n\tvar mode config.DHTMode\n\tif strings.Contains(err.Error(), \"invalid DHT mode\") {\n\t\t// log the offending value and fall back to auto\n\t\tr, err = parseWithMode(ctx, cfg, config.DHTModeAuto)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_ = mode\n}","preventionTips":["Always assign DHT.Mode from the config.DHTMode* constants, never raw strings.","Run `ipfs config --json Routing.DHT` to inspect the value before starting the daemon.","Normalize user input (trim/lowercase) before writing it into the config.","Pin config schema validation in tests that reject unknown DHT.Mode values."],"tags":["config","dht","routing","kubo"],"backgroundTag":"invalid-config-value","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"}