slackhq/nebula · error

invalid port: %d

Error message

invalid port: %d

What it means

newCalculatedRemote stores the port in a uint32-backed field but the wire format only allows 16-bit ports, so it rejects ports below 0 or above 65535 (math.MaxUint16). This catches out-of-range ports supplied through calculated_remotes config entries.

Source

Thrown at calculated_remote.go:31

)

// This allows us to "guess" what the remote might be for a host while we wait
// for the lighthouse response. See "lighthouse.calculated_remotes" in the
// example config file.
type calculatedRemote struct {
	ipNet netip.Prefix
	mask  netip.Prefix
	port  uint32
}

func newCalculatedRemote(cidr, maskCidr netip.Prefix, port int) (*calculatedRemote, error) {
	if maskCidr.Addr().BitLen() != cidr.Addr().BitLen() {
		return nil, fmt.Errorf("invalid mask: %s for cidr: %s", maskCidr, cidr)
	}

	masked := maskCidr.Masked()
	if port < 0 || port > math.MaxUint16 {
		return nil, fmt.Errorf("invalid port: %d", port)
	}

	return &calculatedRemote{
		ipNet: maskCidr,
		mask:  masked,
		port:  uint32(port),
	}, nil
}

func (c *calculatedRemote) String() string {
	return fmt.Sprintf("CalculatedRemote(mask=%v port=%d)", c.ipNet, c.port)
}

func (c *calculatedRemote) ApplyV4(addr netip.Addr) *V4AddrPort {
	// Combine the masked bytes of the "mask" IP with the unmasked bytes of the overlay IP
	maskb := net.CIDRMask(c.mask.Bits(), c.mask.Addr().BitLen())
	mask := binary.BigEndian.Uint32(maskb[:])

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Set the port to a value between 0 and 65535
  2. If the port came from a string, confirm it parses with strconv.Atoi and lands in uint16 range before use
  3. Clamp or validate the port at config-load time in the caller

Example fix

// before
- mask: 10.0.0.0/8
  port: 70000
// after
- mask: 10.0.0.0/8
  port: 4242
Defensive patterns

Strategy: validation

Validate before calling

func validPort(p any) bool {
	switch v := p.(type) {
	case int:
		return v >= 0 && v <= 65535
	case string:
		n, err := strconv.Atoi(v)
		return err == nil && n >= 0 && n <= 65535
	}
	return false
}

Type guard

func isUint16Port(n int) bool { return n >= 0 && n <= math.MaxUint16 }

Try / catch

cr, err := newCalculatedRemote(cidr, maskCidr, port)
if err != nil {
	if strings.HasPrefix(err.Error(), "invalid port:") {
		return fmt.Errorf("port %d out of range 0-65535 for %s", port, cidr)
	}
	return err
}

Prevention

When it happens

Trigger: A calculated_remotes entry whose `port` is negative, exceeds 65535, or a string like "99999" parsed via strconv.Atoi then passed to newCalculatedRemote.

Common situations: Typo'd port numbers in nebula lighthouse config (e.g. 655360 instead of 65536), negative values from bad templating, or unquoted strings that parse to huge integers.

Related errors


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