ipfs/kubo · warning · ErrConnNotFound
conn not found
Error message
conn not found
What it means
ErrConnNotFound is a sentinel error of the CoreAPI swarm interface, defined in core/coreiface/swarm.go. Disconnect returns it when the multiaddr form is used (core/coreapi/swarm.go:89): the node enumerated its live connections and none of them is over the given address, so there is nothing to close.
Source
Thrown at core/coreiface/swarm.go:17
package iface
import (
"context"
"errors"
"time"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/protocol"
ma "github.com/multiformats/go-multiaddr"
)
var (
ErrNotConnected = errors.New("not connected")
ErrConnNotFound = errors.New("conn not found")
)
// ConnectionInfo contains information about a peer
type ConnectionInfo interface {
// ID returns PeerID
ID() peer.ID
// Address returns the multiaddress via which we are connected with the peer
Address() ma.Multiaddr
// Direction returns which way the connection was established
Direction() network.Direction
// Latency returns last known round trip time to the peer
Latency() (time.Duration, error)
// Streams returns list of streams established with the peer
Streams() ([]protocol.ID, error)View on GitHub (pinned to 329838acdf)
Solutions
- Check api.Swarm().Peers(ctx) and disconnect using the exact Address() strings from its output, refreshed at call time
- Prefer the peer-ID form: Disconnect(ctx, peer.ID) — it closes the connection regardless of which address it uses (returning ErrNotConnected instead if already gone)
- Accept errors.Is(err, coreiface.ErrConnNotFound) as a no-op success in cleanup paths
Example fix
// before
addrs, _ := api.Swarm().Peers(ctx) // stale snapshot
_ = addrs[0].Address().String() // connection since dropped
err := api.Swarm().Disconnect(ctx, staleAddr) // ErrConnNotFound
// after
peers, _ := api.Swarm().Peers(ctx)
for _, p := range peers {
if p.ID() == targetID {
err := api.Swarm().Disconnect(ctx, p.ID())
if err != nil && !errors.Is(err, coreiface.ErrConnNotFound) {
return err
}
}
} Defensive patterns
Strategy: try-catch
Validate before calling
peers, err := api.Swarm().Peers(ctx)
if err != nil {
return err
}
found := false
for _, p := range peers {
if p.Address().Equal(targetAddr) {
found = true
break
}
}
if !found {
return nil // nothing to disconnect
}
err = api.Swarm().Disconnect(ctx, targetAddr) Type guard
func isConnNotFoundErr(err error) bool {
return errors.Is(err, coreiface.ErrConnNotFound)
} Try / catch
err := api.Swarm().Disconnect(ctx, addr)
switch {
case err == nil:
// connection closed
case errors.Is(err, coreiface.ErrConnNotFound):
// no live connection on that address: treat as no-op
default:
return fmt.Errorf("disconnect %s: %w", addr, err)
} Prevention
- Snapshot addresses fresh from Swarm().Peers at disconnect time; old snapshots go stale
- Prefer the peer-ID form of Disconnect — it survives address churn (relay swaps, AutoTLS)
- Normalize multiaddrs before comparing; DNS vs IP and circuit forms rarely match literally
- In cleanup code, treat both ErrConnNotFound and ErrNotConnected as success
When it happens
Trigger: Calling api.Swarm().Disconnect(ctx, addr) with a multiaddr that does not match any active connection: the connection dropped already (so Peerstore keeps the addr but no conn exists), a stale relay/circuit address, a DNS address that resolved differently from the dialed form, or a wrong port/scheme typo.
Common situations: Disconnecting a specific connection after a relay circuit was recycled; peers that connected via a different address than advertised (e.g. AutoTLS *.libp2p.direct vs raw TCP); reconnect-and-disconnect races in tests; hardcoding addresses from an earlier Peers() snapshot.
Related errors
- not connected
- no local swarm address for migration node
- fail to resolve the multiaddr:%s
- ambiguous multiaddr %s could refer to %s or %s
- incorrectly formatted address filter in config: %s
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/4148920689480ae7.
Report an issue: GitHub.