ipfs/kubo · error

The Swarm.ResourceMgr.Limits configuration has been removed

Error message

The Swarm.ResourceMgr.Limits configuration has been removed in Kubo 0.19 and should be empty or not present. To set custom libp2p limits, read https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#user-supplied-override-limits

What it means

Swarm.ResourceMgr.Limits was removed in Kubo 0.19; its UnmarshalJSON only accepts an absent key or an empty JSON object and rejects any non-empty content with this migration error. Custom libp2p resource limits must now be supplied via the rcmgr override limits file described in docs/libp2p-resource-management.md.

Source

Thrown at config/types.go:532

type swarmLimits doNotUse

var _ json.Unmarshaler = swarmLimits(false)

func (swarmLimits) 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 Swarm.ResourceMgr.Limits configuration has been removed in Kubo 0.19 and should be empty or not present. To set custom libp2p limits, read https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#user-supplied-override-limits")
		default:
			return err
		}
	}
}

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 {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Remove the Swarm.ResourceMgr.Limits key from config.json (or leave it as an empty object {}).
  2. Configure custom libp2p limits via the user-supplied override limits file per https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md#user-supplied-override-limits.
  3. Run `ipfs config show`, edit out the key, and `ipfs config replace` the cleaned file.

Example fix

// before (config.json)
{"Swarm": {"ResourceMgr": {"Limits": {"System": {"Conns": 9000}}}}}
// after
{"Swarm": {"ResourceMgr": {"Limits": {}}}}
// move overrides to the limits override file (ResourceManager.AdditionalResources / override file per docs)
Defensive patterns

Strategy: validation

Validate before calling

// before starting the daemon, strip removed Limits key
func stripRemovedLimits(cfg map[string]any) {
    if rm, ok := cfg["Swarm"].(map[string]any); ok {
        if r, ok := rm["ResourceMgr"].(map[string]any); ok {
            if lim, ok := r["Limits"].(map[string]any); ok && len(lim) > 0 {
                delete(r, "Limits") // or migrate to override limits file
            }
        }
    }
}

Type guard

func limitsKeyEmpty(cfg map[string]any) bool {
    rm, _ := cfg["Swarm"].(map[string]any)
    r, _ := rm["ResourceMgr"].(map[string]any)
    lim, _ := r["Limits"].(map[string]any)
    return len(lim) == 0
}

Try / catch

if err := node.Start(); err != nil {
    if strings.Contains(err.Error(), "Swarm.ResourceMgr.Limits") {
        // remove/migrate the key and restart
    }
}

Prevention

When it happens

Trigger: Starting a node whose config.json still contains a populated Swarm.ResourceMgr.Limits object (e.g. carried over from a pre-0.19 repo), or setting it via `ipfs config --json Swarm.ResourceMgr.Limits '{...}'`.

Common situations: Upgrading an old node (config migration did not clean the key); copying a colleague's pre-0.19 config; automation tools writing limits back into the removed key.

Related errors


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