ipfs/kubo · error · ErrResolveFailed

could not resolve name

Error message

could not resolve name

What it means

`ErrResolveFailed` is the sentinel error signaling that an IPNS/DNSLink name could not be resolved to a path. `Resolve` and the internal `loadRoot` return it when the namesys lookup fails (record not found, invalid record, timeout) and, as in core/coreapi/name.go, it is used as a base error that gets wrapped with more specific causes before returning.

Source

Thrown at core/coreiface/name.go:12

package iface

import (
	"context"
	"errors"

	"github.com/ipfs/boxo/ipns"
	"github.com/ipfs/boxo/path"
	"github.com/ipfs/kubo/core/coreiface/options"
)

var ErrResolveFailed = errors.New("could not resolve name")

type IpnsResult struct {
	path.Path
	Err error
}

// NameAPI specifies the interface to IPNS.
//
// IPNS is a PKI namespace, where names are the hashes of public keys, and the
// private key enables publishing new (signed) values. In both publish and
// resolve, the default name used is the node's own PeerID, which is the hash of
// its public key.
//
// You can use .Key API to list and generate more names and their respective keys.
type NameAPI interface {
	// Publish announces new IPNS name
	Publish(ctx context.Context, path path.Path, opts ...options.NamePublishOption) (ipns.Name, error)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Verify the name actually resolves: check the IPNS record (`ipfs routing get /ipns/<name>` or `ipfs name resolve --norepensive`... i.e. re-run with `ipfs name resolve -r`/inspect via `ipfs dht findvalue /ipns/<name>`) and confirm DNSLink TXT records with `dig TXT _dnslink.<domain>`.
  2. Republish the IPNS record from the owning key (`ipfs name publish <path>`) if it expired or was never published.
  3. Increase timeout/retry around resolution (records may take time to propagate) and ensure the daemon is online; check `errors.Is(err, coreiface.ErrResolveFailed)` to distinguish resolution failure from other errors.

Example fix

// before
p, err := api.Name().Resolve(ctx, name)
if err != nil { return err }
// after
p, err := api.Name().Resolve(ctx, name)
if err != nil {
    if errors.Is(err, coreiface.ErrResolveFailed) {
        return fmt.Errorf("%w: check record exists/expired and DNSLink TXT", err)
    }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

// Before resolving, verify the record exists:
// - IPNS: `ipfs name resolve <name>` or `ipfs routing get /ipns/<name>`
// - DNSLink: `dig TXT _dnslink.<domain>` returns a dnslink=/ipfs/... entry

Try / catch

p, err := api.Name().Resolve(ctx, name)
if err != nil {
    if errors.Is(err, coreiface.ErrResolveFailed) {
        // retry with backoff; records may still be propagating
        p, err = resolveWithRetry(ctx, name, 3)
    }
    if err != nil { return fmt.Errorf("resolve %s: %w", name, err) }
}

Prevention

When it happens

Trigger: Calling `api.Name().Resolve(ctx, name)` for an IPNS name with no published record, an expired/invalid record, or a DNSLink domain without a TXT record; also returned by the mock namesys in gateway tests when a name is missing from the fixture map.

Common situations: `ipfs name resolve <peerid>` for a name that was never published or whose record expired; DNSLink domains missing `_dnslink.` TXT entries; network partitions/timeouts during DHT lookup of the IPNS record; stale local caches with republisher turned off.

Related errors


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