ipfs/kubo · error

unrecognized reachability option: %s

Error message

unrecognized reachability option: %s

What it means

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.

Source

Thrown at core/node/libp2p/libp2p.go:102

	for i, opt := range enabledOptions {
		p2pOpts[i] = opt.opt
	}
	return libp2p.ChainOptions(p2pOpts...)
}

func ForceReachability(val *config.OptionalString) func() (opts Libp2pOpts, err error) {
	return func() (opts Libp2pOpts, err error) {
		if val.IsDefault() {
			return
		}
		v := val.WithDefault("unrecognized")
		switch v {
		case "public":
			opts.Opts = append(opts.Opts, libp2p.ForceReachabilityPublic())
		case "private":
			opts.Opts = append(opts.Opts, libp2p.ForceReachabilityPrivate())
		default:
			return opts, fmt.Errorf("unrecognized reachability option: %s", v)
		}
		return
	}
}

// NonPublicAddrPublishing controls whether non-globally-routable addresses stay
// in the peerstore self-entry and the signed peer record. Leaving the flag unset
// passes no option, so go-libp2p's own default decides.
func NonPublicAddrPublishing(val config.Flag) func() (opts Libp2pOpts) {
	return func() (opts Libp2pOpts) {
		if val == config.Default {
			return
		}
		opts.Opts = append(opts.Opts, libp2p.NonPublicAddrPublishing(val == config.True))
		return
	}
}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set the value to exactly "public" or "private": `ipfs config <ReachabilityKey> public`
  2. Consult docs/config.md for the exact accepted values of the option you are setting
  3. Remove the setting entirely to let AutoNAT determine reachability dynamically (recommended default)

Example fix

// before (config.json)
"Swarm": { "Reachability": "auto" }
// after
"Swarm": { "Reachability": "public" }
Defensive patterns

Strategy: validation

Validate before calling

switch v := cfg.Swarm.Reachability; v {
case "", "public", "private":
    // ok
default:
    return fmt.Errorf("reachability must be public or private, got %q", v)
}

Prevention

When it happens

Trigger: 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.

Common situations: Typos like "Public", "auto", or "nat"; users guessing valid values instead of consulting docs/config.md; scripts interpolating empty or malformed values.

Related errors


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