slackhq/nebula · error

invalid mask: %s

Error message

invalid mask: %s

What it means

This error is returned by newCalculatedRemotesEntryFromConfig when the 'mask' value in a calculated_remotes config entry cannot be parsed as an IP prefix. Nebula requires the mask to be a valid CIDR prefix (e.g. 10.0.0.0/8) so it can compute calculated remote hosts by masking target IPs. Parse failures of the string with netip.ParsePrefix produce this message carrying the raw offending value.

Source

Thrown at calculated_remote.go:142

}

func newCalculatedRemotesEntryFromConfig(cidr netip.Prefix, raw any) (*calculatedRemote, error) {
	rawMap, ok := raw.(map[string]any)
	if !ok {
		return nil, fmt.Errorf("invalid type: %T", raw)
	}

	rawValue := rawMap["mask"]
	if rawValue == nil {
		return nil, fmt.Errorf("missing mask: %v", rawMap)
	}
	rawMask, ok := rawValue.(string)
	if !ok {
		return nil, fmt.Errorf("invalid mask (type %T): %v", rawValue, rawValue)
	}
	maskCidr, err := netip.ParsePrefix(rawMask)
	if err != nil {
		return nil, fmt.Errorf("invalid mask: %s", rawMask)
	}

	var port int
	rawValue = rawMap["port"]
	if rawValue == nil {
		return nil, fmt.Errorf("missing port: %v", rawMap)
	}
	switch v := rawValue.(type) {
	case int:
		port = v
	case string:
		port, err = strconv.Atoi(v)
		if err != nil {
			return nil, fmt.Errorf("invalid port: %s: %w", v, err)
		}
	default:
		return nil, fmt.Errorf("invalid port (type %T): %v", rawValue, rawValue)
	}

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Change the mask value to a valid CIDR prefix, e.g. mask: 10.0.0.0/8 instead of a dotted netmask
  2. Verify the prefix length is in range (0-32 for IPv4, 0-128 for IPv6)
  3. Check the config value is not quoted or padded with stray whitespace/characters
  4. Validate locally with `netip.ParsePrefix` or an online CIDR checker before deploying

Example fix

// before
calculated_remotes:
  - mask: 255.255.0.0
    port: 4242
// after
calculated_remotes:
  - mask: 10.0.0.0/16
    port: 4242
Defensive patterns

Strategy: validation

Validate before calling

func validMask(v string) bool {
    _, err := netip.ParsePrefix(strings.TrimSpace(v))
    return err == nil
}
// before launching nebula: ensure every calculated_remotes mask passes validMask

Type guard

func asMaskString(raw any) (string, bool) {
    s, ok := raw.(string)
    if !ok || !validMask(s) {
        return "", false
    }
    return s, true
}

Try / catch

if err != nil {
    var cfgErr *ConfigError
    if errors.As(err, &cfgErr) {
        log.Fatalf("calculated_remotes mask invalid: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling newCalculatedRemotesListFromConfig with a config map whose calculated_remotes entry has a 'mask' key set to a string that is not a valid CIDR prefix, e.g. mask: 255.255.0.0 or mask: 10.0.0.0/33 or mask: not-a-mask.

Common situations: Users copying subnet masks from netmask notation (255.255.255.0) instead of CIDR (/24), typos in the prefix length, or omitting the /prefix part entirely when writing the Nebula YAML config.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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