{"record":{"id":"4148920689480ae7","repo":"ipfs/kubo","slug":"conn-not-found","errorCode":null,"errorMessage":"conn not found","messagePattern":"conn not found","errorType":"exception","errorClass":"ErrConnNotFound","httpStatus":null,"severity":"warning","filePath":"core/coreiface/swarm.go","lineNumber":17,"sourceCode":"package iface\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/libp2p/go-libp2p/core/network\"\n\t\"github.com/libp2p/go-libp2p/core/peer\"\n\t\"github.com/libp2p/go-libp2p/core/protocol\"\n\n\tma \"github.com/multiformats/go-multiaddr\"\n)\n\nvar (\n\tErrNotConnected = errors.New(\"not connected\")\n\tErrConnNotFound = errors.New(\"conn not found\")\n)\n\n// ConnectionInfo contains information about a peer\ntype ConnectionInfo interface {\n\t// ID returns PeerID\n\tID() peer.ID\n\n\t// Address returns the multiaddress via which we are connected with the peer\n\tAddress() ma.Multiaddr\n\n\t// Direction returns which way the connection was established\n\tDirection() network.Direction\n\n\t// Latency returns last known round trip time to the peer\n\tLatency() (time.Duration, error)\n\n\t// Streams returns list of streams established with the peer\n\tStreams() ([]protocol.ID, error)","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/coreiface/swarm.go#L1-L35","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\naddrs, _ := api.Swarm().Peers(ctx) // stale snapshot\n_ = addrs[0].Address().String()     // connection since dropped\nerr := api.Swarm().Disconnect(ctx, staleAddr) // ErrConnNotFound\n\n// after\npeers, _ := api.Swarm().Peers(ctx)\nfor _, p := range peers {\n    if p.ID() == targetID {\n        err := api.Swarm().Disconnect(ctx, p.ID())\n        if err != nil && !errors.Is(err, coreiface.ErrConnNotFound) {\n            return err\n        }\n    }\n}","handlingStrategy":"try-catch","validationCode":"peers, err := api.Swarm().Peers(ctx)\nif err != nil {\n    return err\n}\nfound := false\nfor _, p := range peers {\n    if p.Address().Equal(targetAddr) {\n        found = true\n        break\n    }\n}\nif !found {\n    return nil // nothing to disconnect\n}\nerr = api.Swarm().Disconnect(ctx, targetAddr)","typeGuard":"func isConnNotFoundErr(err error) bool {\n    return errors.Is(err, coreiface.ErrConnNotFound)\n}","tryCatchPattern":"err := api.Swarm().Disconnect(ctx, addr)\nswitch {\ncase err == nil:\n    // connection closed\ncase errors.Is(err, coreiface.ErrConnNotFound):\n    // no live connection on that address: treat as no-op\ndefault:\n    return fmt.Errorf(\"disconnect %s: %w\", addr, err)\n}","preventionTips":["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"],"tags":["swarm","libp2p","network","multiaddr"],"backgroundTag":"connection-not-found","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}