slackhq/nebula · error

unable to find host with relay

Error message

unable to find host with relay

What it means

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.

Source

Thrown at hostmap.go:620

		r, ok := h.relayState.QueryRelayForByIp(targetIp)
		if ok && r.State == Established {
			return h, r, nil
		}
	}

	if list, ok := hm.moreHosts[relayHostIp]; ok {
		// list[0] is the primary we already checked
		for _, h := range list[1:] {
			for _, targetIp := range targetIps {
				r, ok := h.relayState.QueryRelayForByIp(targetIp)
				if ok && r.State == Established {
					return h, r, nil
				}
			}
		}
	}

	return nil, nil, errors.New("unable to find host with relay")
}

func (hm *HostMap) unlockedDisestablishVpnAddrRelayFor(hi *HostInfo) {
	for _, relayHostIp := range hi.relayState.CopyRelayIps() {
		for _, h := range hm.unlockedGetHostList(relayHostIp) {
			h.relayState.UpdateRelayForByIpState(hi.vpnAddrs[0], Disestablished)
		}
	}
	for _, rs := range hi.relayState.CopyAllRelayFor() {
		if rs.Type == ForwardingType {
			for _, h := range hm.unlockedGetHostList(rs.PeerAddr) {
				h.relayState.UpdateRelayForByIpState(hi.vpnAddrs[0], Disestablished)
			}
		}
	}
}

func (hm *HostMap) queryVpnAddr(vpnIp netip.Addr, promoteIfce *Interface) *HostInfo {

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Trigger a re-handshake with the target peer to re-establish the relay
  2. Check that the target peer is online and reachable through the relay
  3. Inspect relay state logs (Established vs Disestablished) for the target IP
  4. Restart the relay host connection so relay state is rebuilt
Defensive patterns

Strategy: fallback

Validate before calling

// check relay state before sending relayed traffic
h := hm.Hosts[relayHostIp]
if h != nil {
    if r, ok := h.relayState.QueryRelayForByIp(targetIp); !ok || r.State != Established {
        // relay not established: trigger re-handshake
    }
}

Try / catch

if _, _, err := hm.QueryRelayForByIpVpnAddr(relayHostIp, targetIps); err != nil { /* treat as no-relay: fall back to direct connection attempt */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/6f06c8d93f6c545b. Report an issue: GitHub.