slackhq/nebula · error
ErrInvalidLocalIP
ErrInvalidLocalIP
Error message
local address is not in list of handled local addresses
What it means
ErrInvalidLocalIP is a sentinel error declared at firewall.go:421 with message "local address is not in list of handled local addresses". Firewall.Drop returns it when the packet's destination (local) address is not contained in the firewall's routableNetworks set (firewall.go:457), meaning the packet is not addressed to any IP this node is configured to handle. This protects against packets destined to addresses the node does not own or route.
Source
Thrown at firewall.go:421
"table", table,
"rule", i,
"warning", warning,
)
}
err = fw.AddRule(inbound, proto, startPort, endPort, r.Groups, r.Host, r.Cidr, r.LocalCidr, r.CAName, r.CASha)
if err != nil {
return fmt.Errorf("%s rule #%v; `%s`", table, i, err)
}
}
return nil
}
var ErrUnknownNetworkType = errors.New("unknown network type")
var ErrPeerRejected = errors.New("remote address is not within a network that we handle")
var ErrInvalidRemoteIP = errors.New("remote address is not in remote certificate networks")
var ErrInvalidLocalIP = errors.New("local address is not in list of handled local addresses")
var ErrNoMatchingRule = errors.New("no matching rule in firewall table")
// Drop returns an error if the packet should be dropped, explaining why. It
// returns nil if the packet should not be dropped.
func (f *Firewall) Drop(fp firewall.Packet, incoming bool, h *HostInfo, caPool *cert.CAPool, localCache firewall.ConntrackCache) error {
// Make sure remote address matches nebula certificate, and determine how to treat it
if h.networks == nil {
// Simple case: Certificate has one address and no unsafe networks
if h.vpnAddrs[0] != fp.RemoteAddr {
f.metrics(incoming).droppedRemoteAddr.Inc(1)
return ErrInvalidRemoteIP
}
} else {
nwType, ok := h.networks.Lookup(fp.RemoteAddr)
if !ok {
f.metrics(incoming).droppedRemoteAddr.Inc(1)
return ErrInvalidRemoteIP
}View on GitHub (pinned to dd8f660c0a)
Solutions
- Add the destination network to the node's handled/routable networks config so f.routableNetworks contains fp.LocalAddr
- Fix the packet generation/dialing side to use the node's actual configured address as destination
- Verify the tun interface and nebula config agree on the node's address after re-addressing
- If this is a forwarding/relay setup, explicitly configure the relayed networks as routable
Example fix
// before (test-style packet with bogus destination)
tc.p.LocalAddr = netip.MustParseAddr("1.2.3.8") // not in routableNetworks
// after
tc.p.LocalAddr = myAddr // an address contained in the node's handled local prefixes Defensive patterns
Strategy: validation
Validate before calling
// ensure the destination is in the node's handled local networks before sending/Drop
func localAddrOK(routable *netipx.IPSet, local netip.Addr) bool {
return routable.Contains(local)
} Try / catch
if err := fw.Drop(pkt, incoming, host, caPool, cache); err != nil {
if errors.Is(err, firewall.ErrInvalidLocalIP) {
// packet is addressed outside handled local networks: fix destination or routable config
}
} Prevention
- Keep the node's tun address and configured routable networks in sync after any re-addressing
- Only construct packets to addresses the node advertises as its own
- When relaying/forwarding, explicitly add the relayed ranges to the handled networks
- In tests, derive packet LocalAddr from the setup's prefix rather than hardcoding unrelated IPs
When it happens
Trigger: Firewall.Drop is called with a firewall.Packet whose fp.LocalAddr (destination IP) is outside the prefix set configured as the node's routable networks (f.routableNetworks.Contains fails). See firewall.go:457 and the test at firewall_test.go:1645 where LocalAddr is forced to 1.2.3.8.
Common situations: Wrong 'listen host' / tun route setup where the node's tun interface address is not among handled networks; packets routed to the node for forwarding that it is not configured to accept; typos in config networks; sending to an old node IP after re-addressing without updating routable networks; test harnesses constructing packets with arbitrary LocalAddr values.
Related errors
- ErrPeerRejected
- ErrInvalidRemoteIP
- unknown protocol %v
- %s failed to parse, should be an array of rules
- %s rule #%v; %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/06d584ce62343124.
Report an issue: GitHub.