slackhq/nebula · error
unknown address type %v
Error message
unknown address type %v
What it means
addIp handles only IPv4 (Is4 family path) and IPv6 (Is6 path) addresses. If the configured netip.Prefix is neither (zero-value Prefix, or an unparseable fallback), it returns this error at the end of the function. It is a defensive guard — in practice it means the configured VPN network list contained a malformed or zero Prefix.
Source
Thrown at overlay/tun_freebsd.go:471
Preferred: 0,
Vltime: 0xffffffff,
Pltime: 0xffffffff,
},
Flags: IN6_IFF_NODAD,
}
s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_DGRAM, syscall.IPPROTO_IP)
if err != nil {
return err
}
defer syscall.Close(s)
if err := ioctl(uintptr(s), OSIOCAIFADDR_IN6, uintptr(unsafe.Pointer(&ifr))); err != nil {
return fmt.Errorf("failed to set tun address %s: %s", cidr.Addr().String(), err)
}
return nil
}
return fmt.Errorf("unknown address type %v", cidr)
}
func (t *tun) Activate() error {
// Setup our default MTU
err := t.setMTU()
if err != nil {
return err
}
linkAddr, err := getLinkAddr(t.Device)
if err != nil {
return err
}
if linkAddr == nil {
return fmt.Errorf("unable to discover link_addr for tun interface")
}
t.linkAddr = linkAddr
View on GitHub (pinned to dd8f660c0a)
Solutions
- Validate all prefixes with netip.ParsePrefix and check the error at config load time
- Reject the zero-value Prefix{} explicitly before constructing the tun
- Log and skip invalid network entries instead of passing them to addIp
- Check where vpnNetworks is populated for ignored parse errors
Example fix
// before
nets = append(nets, netip.PrefixFrom(cfgNet, bits)) // may yield zero Prefix on bad input
// after
p, err := netip.ParsePrefix(cfgNet)
if err != nil {
return fmt.Errorf("invalid vpn network %q: %w", cfgNet, err)
}
nets = append(nets, p) Defensive patterns
Strategy: validation
Validate before calling
func validateNetworks(nets []netip.Prefix) error {
for _, n := range nets {
if !n.IsValid() || (!n.Addr().Is4() && !n.Addr().Is6()) {
return fmt.Errorf("invalid vpn network prefix: %v", n)
}
}
return nil
}
// call before newTun/Activate: validateNetworks(vpnNetworks) Type guard
func isValidPrefix(p netip.Prefix) bool { return p.IsValid() && (p.Addr().Is4() || p.Addr().Is6()) } Try / catch
if err := dev.Activate(); err != nil {
if strings.Contains(err.Error(), "unknown address type") {
return fmt.Errorf("config error: vpnNetworks contains an invalid/zero prefix: %w", err)
}
return err
} Prevention
- Always check the error from netip.ParsePrefix; never store zero-valued Prefix
- Reject netip.Prefix{} and PrefixFrom(0,0) at config validation
- Fuzz/validate the network list before constructing the device
- Avoid placeholder config values that reach addIp unvalidated
When it happens
Trigger: Activate() → addIp() receiving a netip.Prefix that is neither Is4 nor Is6 — typically the zero value netip.Prefix{} resulting from a failed ParsePrefix whose error was ignored, or an empty/placeholder network list entry.
Common situations: Config parsing that swallows errors and stores zero-valued prefixes; building vpnNetworks programmatically with netip.PrefixFrom(0,0); template/placeholder config values never replaced.
Related errors
- unable to determine IP version from packet
- newTunFromFd not supported in FreeBSD
- failed to set tun device as nonblocking: %w
- failed to create shutdown pipe: %w
- failed to set tun address %s: %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/0a0c2caf72be0743.
Report an issue: GitHub.