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

  1. Validate all prefixes with netip.ParsePrefix and check the error at config load time
  2. Reject the zero-value Prefix{} explicitly before constructing the tun
  3. Log and skip invalid network entries instead of passing them to addIp
  4. 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

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


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