ipfs/kubo · error
could not perform version check due to missing or incompatib
Error message
could not perform version check due to missing or incompatible DHT configuration
What it means
DetectNewKuboVersion relies on the Amino DHT client (FullRT) retaining peer information about previously seen swarm peers. When the node claims to have an active DHT client (nd.HasActiveDHTClient()) but nd.DHTClient is not a *fullrt.FullRT, the code cannot enumerate seen peers and returns this error. It signals an unexpected/incompatible DHT implementation at runtime.
Source
Thrown at core/commands/version.go:261
if peerVersion.GreaterThan(greatestVersionSeen) {
greatestVersionSeen = peerVersion
}
}
processPeerstoreEntry := func(id peer.ID) {
if v, err := nd.Peerstore.Get(id, "AgentVersion"); err == nil {
recordPeerVersion(v.(string))
} else if errors.Is(err, pstore.ErrNotFound) { // ignore noop
} else { // a bug, usually.
log.Errorw("failed to get agent version from peerstore", "error", err)
}
}
// Amino DHT client keeps information about previously seen peers
if nd.HasActiveDHTClient() && nd.DHTClient != nd.DHT {
client, ok := nd.DHTClient.(*fullrt.FullRT)
if !ok {
return VersionCheckOutput{}, errors.New("could not perform version check due to missing or incompatible DHT configuration")
}
for _, p := range client.Stat() {
processPeerstoreEntry(p)
}
} else if nd.DHT != nil && nd.DHT.WAN != nil {
for _, pi := range nd.DHT.WAN.RoutingTable().GetPeerInfos() {
processPeerstoreEntry(pi.Id)
}
} else if nd.DHT != nil && nd.DHT.LAN != nil {
for _, pi := range nd.DHT.LAN.RoutingTable().GetPeerInfos() {
processPeerstoreEntry(pi.Id)
}
} else {
return VersionCheckOutput{}, errors.New("could not perform version check due to missing or incompatible DHT configuration")
}
if minPercent < 1 || minPercent > 100 {
if minPercent == 0 {View on GitHub (pinned to 329838acdf)
Solutions
- Run stock Kubo routing configuration (no custom DHT replacement) when using 'ipfs version check'
- Update to a matching official kubo release so nd.DHTClient is the standard FullRT client
- If you maintain a fork/plugin that swaps the DHT, either provide a FullRT-compatible client or skip the swarm version check
- Check config for experimental routing flags that alter DHT setup and reset them to defaults
Defensive patterns
Strategy: fallback
Validate before calling
if nd.HasActiveDHTClient() {
if _, ok := nd.DHTClient.(*fullrt.FullRT); !ok {
return errors.New("swarm version check requires the standard FullRT DHT client")
}
} Type guard
func isFullRT(v interface{}) bool {
_, ok := v.(*fullrt.FullRT)
return ok
} Try / catch
out, err := DetectNewKuboVersion(nd, pct)
if err != nil && strings.Contains(err.Error(), "missing or incompatible DHT configuration") {
log.Warnf("swarm version check unavailable: %v", err)
return VersionCheckOutput{}, nil
}
return out, err Prevention
- Run stock routing configuration when using swarm version checks
- Don't swap nd.DHTClient with custom implementations in forks
- Keep kubo and go-libp2p-kad-dht versions aligned via official releases
When it happens
Trigger: 'ipfs version check' or the daemon's periodic swarm version check on a node where DHTClient is set but is not a FullRT instance — e.g. a custom or mocked DHT client, or an internal build where the client type changed.
Common situations: Running with experimental/custom routing configurations that swap the DHT implementation; plugin or fork code replacing the DHT client; version skew between kubo and its go-libp2p-kad-dht dependency after a hand-rolled dependency bump.
Related errors
- Version.SwarmCheckPercentThreshold must be between 1 and 100
- Routing.AcceleratedDHTClient option is set even tho Routing.
- failed to raise ulimit to IPFS_FD_MAX (%d): set to %d
- invalid provide strategy: empty token in %q
- unknown provide strategy token: %q in %q
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/d860e718e20e6e96.
Report an issue: GitHub.