{"record":{"id":"6f06c8d93f6c545b","repo":"slackhq/nebula","slug":"unable-to-find-host-with-relay","errorCode":null,"errorMessage":"unable to find host with relay","messagePattern":"unable to find host with relay","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hostmap.go","lineNumber":620,"sourceCode":"\t\tr, ok := h.relayState.QueryRelayForByIp(targetIp)\n\t\tif ok && r.State == Established {\n\t\t\treturn h, r, nil\n\t\t}\n\t}\n\n\tif list, ok := hm.moreHosts[relayHostIp]; ok {\n\t\t// list[0] is the primary we already checked\n\t\tfor _, h := range list[1:] {\n\t\t\tfor _, targetIp := range targetIps {\n\t\t\t\tr, ok := h.relayState.QueryRelayForByIp(targetIp)\n\t\t\t\tif ok && r.State == Established {\n\t\t\t\t\treturn h, r, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil, nil, errors.New(\"unable to find host with relay\")\n}\n\nfunc (hm *HostMap) unlockedDisestablishVpnAddrRelayFor(hi *HostInfo) {\n\tfor _, relayHostIp := range hi.relayState.CopyRelayIps() {\n\t\tfor _, h := range hm.unlockedGetHostList(relayHostIp) {\n\t\t\th.relayState.UpdateRelayForByIpState(hi.vpnAddrs[0], Disestablished)\n\t\t}\n\t}\n\tfor _, rs := range hi.relayState.CopyAllRelayFor() {\n\t\tif rs.Type == ForwardingType {\n\t\t\tfor _, h := range hm.unlockedGetHostList(rs.PeerAddr) {\n\t\t\t\th.relayState.UpdateRelayForByIpState(hi.vpnAddrs[0], Disestablished)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (hm *HostMap) queryVpnAddr(vpnIp netip.Addr, promoteIfce *Interface) *HostInfo {","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/hostmap.go#L602-L638","documentation":"Same lookup path as 'unable to find host', but here the relay host WAS found in the HostMap yet its relayState has no relay entry for the target IP with State == Established. The host exists but cannot currently relay traffic to the requested target.","triggerScenarios":"QueryRelayForByIp returns no entry for targetIp, or the relay exists but its state is not Established (e.g. Disestablished/Pending), via unlockedQueryRelayForByIpVpnAddr in hostmap.go.","commonSituations":"Relay was torn down (unlockedDisestablishVpnAddrRelayFor marks it Disestablished) while packets still flow; target peer behind the relay went offline; handshake over the relay not completed.","solutions":["Trigger a re-handshake with the target peer to re-establish the relay","Check that the target peer is online and reachable through the relay","Inspect relay state logs (Established vs Disestablished) for the target IP","Restart the relay host connection so relay state is rebuilt"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// check relay state before sending relayed traffic\nh := hm.Hosts[relayHostIp]\nif h != nil {\n    if r, ok := h.relayState.QueryRelayForByIp(targetIp); !ok || r.State != Established {\n        // relay not established: trigger re-handshake\n    }\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := hm.QueryRelayForByIpVpnAddr(relayHostIp, targetIps); err != nil { /* treat as no-relay: fall back to direct connection attempt */ }","preventionTips":["Treat Disestablished relay state as a signal to re-handshake","Verify target peers are online before routing through relays","Log relay state transitions to catch premature teardown"],"tags":["network","relay","hostmap","nebula"],"backgroundTag":"relay-host-not-found","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}