ipfs/kubo · error

The Experimental.AcceleratedDHTClient key has been moved to

Error message

The Experimental.AcceleratedDHTClient key has been moved to Routing.AcceleratedDHTClient in Kubo 0.21, please use this new key and remove the old one.

What it means

Experimental.AcceleratedDHTClient was moved to Routing.AcceleratedDHTClient in Kubo 0.21. Its UnmarshalJSON only accepts an absent key or an empty object and rejects any other content, forcing users to adopt the new location explicitly.

Source

Thrown at config/types.go:556

type experimentalAcceleratedDHTClient doNotUse

var _ json.Unmarshaler = experimentalAcceleratedDHTClient(false)

func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error {
	d := json.NewDecoder(bytes.NewReader(b))
	for {
		switch tok, err := d.Token(); err {
		case io.EOF:
			return nil
		case nil:
			switch tok {
			case json.Delim('{'), json.Delim('}'):
				// accept empty objects
				continue
			}
			//nolint
			return fmt.Errorf("The Experimental.AcceleratedDHTClient key has been moved to Routing.AcceleratedDHTClient in Kubo 0.21, please use this new key and remove the old one.")
		default:
			return err
		}
	}
}

// doNotUse is a type you must not use, it should be struct{} but encoding/json
// does not support omitempty on structs and I can't be bothered to write custom
// marshalers on all structs that have a doNotUse field.
type doNotUse bool

type graphsyncEnabled doNotUse

var _ json.Unmarshaler = graphsyncEnabled(false)

func (graphsyncEnabled) UnmarshalJSON(b []byte) error {
	d := json.NewDecoder(bytes.NewReader(b))
	for {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set the value at the new location: `ipfs config --bool Routing.AcceleratedDHTClient true`.
  2. Remove the old key: `ipfs config delete Experimental.AcceleratedDHTClient` (or strip it from config.json).
  3. Restart the daemon after the change.

Example fix

// before (config.json)
{"Experimental": {"AcceleratedDHTClient": true}}
// after
{"Routing": {"AcceleratedDHTClient": true}}
Defensive patterns

Strategy: validation

Validate before calling

// detect stale key before daemon start
func hasOldAcceleratedDHT(cfg map[string]any) bool {
    exp, _ := cfg["Experimental"].(map[string]any)
    _, ok := exp["AcceleratedDHTClient"]
    return ok
}

Type guard

func usesNewDHTKey(cfg map[string]any) bool {
    exp, _ := cfg["Experimental"].(map[string]any)
    v, present := exp["AcceleratedDHTClient"]
    if !present { return true }
    b, isObj := v.(map[string]any)
    return isObj && len(b) == 0
}

Try / catch

if err := node.Start(); err != nil {
    if strings.Contains(err.Error(), "Experimental.AcceleratedDHTClient") {
        // move to Routing.AcceleratedDHTClient and delete old key
    }
}

Prevention

When it happens

Trigger: Starting a node whose config.json still contains a non-empty Experimental.AcceleratedDHTClient value after upgrading to Kubo >= 0.21.

Common situations: Upgraded nodes where the old flag was set to true; copied configs from older deployments; provisioning scripts still writing the Experimental key.

Related errors


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