{"record":{"id":"3b22f9c21e498951","repo":"ipfs/kubo","slug":"unrecognized-reachability-option-s","errorCode":null,"errorMessage":"unrecognized reachability option: %s","messagePattern":"unrecognized reachability option: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/node/libp2p/libp2p.go","lineNumber":102,"sourceCode":"\tfor i, opt := range enabledOptions {\n\t\tp2pOpts[i] = opt.opt\n\t}\n\treturn libp2p.ChainOptions(p2pOpts...)\n}\n\nfunc ForceReachability(val *config.OptionalString) func() (opts Libp2pOpts, err error) {\n\treturn func() (opts Libp2pOpts, err error) {\n\t\tif val.IsDefault() {\n\t\t\treturn\n\t\t}\n\t\tv := val.WithDefault(\"unrecognized\")\n\t\tswitch v {\n\t\tcase \"public\":\n\t\t\topts.Opts = append(opts.Opts, libp2p.ForceReachabilityPublic())\n\t\tcase \"private\":\n\t\t\topts.Opts = append(opts.Opts, libp2p.ForceReachabilityPrivate())\n\t\tdefault:\n\t\t\treturn opts, fmt.Errorf(\"unrecognized reachability option: %s\", v)\n\t\t}\n\t\treturn\n\t}\n}\n\n// NonPublicAddrPublishing controls whether non-globally-routable addresses stay\n// in the peerstore self-entry and the signed peer record. Leaving the flag unset\n// passes no option, so go-libp2p's own default decides.\nfunc NonPublicAddrPublishing(val config.Flag) func() (opts Libp2pOpts) {\n\treturn func() (opts Libp2pOpts) {\n\t\tif val == config.Default {\n\t\t\treturn\n\t\t}\n\t\topts.Opts = append(opts.Opts, libp2p.NonPublicAddrPublishing(val == config.True))\n\t\treturn\n\t}\n}\n","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/node/libp2p/libp2p.go#L84-L120","documentation":"Swarm.RelayService / reachability configuration accepts only the strings \"public\" or \"private\" to force libp2p's AutoNAT reachability. Any other non-empty value in the config reaches this default branch and aborts option building with the offending value named.","triggerScenarios":"Setting the relevant config key (e.g. Swarm.DisableNatPortMap-adjacent reachability option, `ipfs config --json Swarm.RelayClient` style string field) to something other than \"public\"/\"private\", then starting the daemon or building the libp2p options.","commonSituations":"Typos like \"Public\", \"auto\", or \"nat\"; users guessing valid values instead of consulting docs/config.md; scripts interpolating empty or malformed values.","solutions":["Set the value to exactly \"public\" or \"private\": `ipfs config <ReachabilityKey> public`","Consult docs/config.md for the exact accepted values of the option you are setting","Remove the setting entirely to let AutoNAT determine reachability dynamically (recommended default)"],"exampleFix":"// before (config.json)\n\"Swarm\": { \"Reachability\": \"auto\" }\n// after\n\"Swarm\": { \"Reachability\": \"public\" }","handlingStrategy":"validation","validationCode":"switch v := cfg.Swarm.Reachability; v {\ncase \"\", \"public\", \"private\":\n    // ok\ndefault:\n    return fmt.Errorf(\"reachability must be public or private, got %q\", v)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use the literal strings \"public\" or \"private\" for reachability config","Delete the option to let AutoNAT decide dynamically instead of forcing a value","Check docs/config.md for accepted values before writing new options"],"tags":["libp2p","config","nat"],"backgroundTag":"invalid-enum-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"}