slackhq/nebula · error
ErrUnknownNetworkType
ErrUnknownNetworkType
Error message
unknown network type
What it means
ErrUnknownNetworkType in firewall.go is returned by Firewall.Drop when the packet's network type (the switch over conn/network classification) matches none of the handled cases. The code labels it 'should never happen', so it indicates an internal classification bug or an unexpected packet category reaching the firewall rather than a policy decision.
Source
Thrown at firewall.go:418
if warning := r.sanity(); warning != nil {
l.Warn("firewall rule sanity check",
"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 {View on GitHub (pinned to dd8f660c0a)
Solutions
- Log the offending packet's network type at the Drop site to identify the unhandled classification.
- Update the switch in Drop to handle the new network type explicitly.
- Fix the upstream classifier so only known network types reach the firewall.
- Check for recent custom modifications to firewall or packet-parsing code that introduced the type.
Example fix
// before
default:
f.metrics(incoming).droppedRemoteAddr.Inc(1)
return ErrUnknownNetworkType
// after
case cert.Curve_WhateverNewType: // handle the missing case explicitly
return f.checkRule(...)
default:
f.metrics(incoming).droppedRemoteAddr.Inc(1)
return fmt.Errorf("unknown network type %v: %w", networkType, ErrUnknownNetworkType) Defensive patterns
Strategy: try-catch
Validate before calling
// before feeding packets to the firewall, ensure the classification is known
switch pkt.NetworkType() {
case ipv4Type, ipv6Type:
// ok
default:
return fmt.Errorf("unclassifiable packet, refusing to pass to firewall")
} Type guard
func isKnownNetworkType(t NetworkType) bool {
return t == IPv4 || t == IPv6
} Try / catch
if err := f.Drop(pkt, incoming); err != nil {
if errors.Is(err, ErrUnknownNetworkType) {
log.Printf("BUG: unhandled network type %v; dropping and reporting", pkt.NetworkType())
reportBug(pkt)
return // drop is safe; do not retry
}
// other firewall errors (no matching rule, invalid IP) handled separately
} Prevention
- Treat this error as a bug signal: alert/log it rather than silently dropping.
- Extend Drop's switch whenever new network types are introduced.
- Keep packet classification and firewall checks in lockstep via shared constants.
- Fuzz/soak test the tunnel parser so malformed packets are rejected before classification.
When it happens
Trigger: Drop() called with a packet whose network type falls into the default branch at firewall.go:450 — i.e. a classification outside IPv4/IPv6 (or the handled host/network cases) reaches the switch.
Common situations: Bugs in tunnel/routing code feeding unclassified packets to the firewall; custom patches adding new network types without updating Drop's switch; corrupted packet metadata from unsafe memory handling.
Related errors
- %s rule #%v; `%s`
- start port was lower than end port
- only one of group or groups should be defined, both provided
- groups spec [%s] contains the group '"any". This rule will i
- groups specified as %s, but host=any will match any host, re
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/447419e63d5ad0e6.
Report an issue: GitHub.