slackhq/nebula · error

config `%s` has invalid type: %T

Error message

config `%s` has invalid type: %T

What it means

newAllowList parses a config key (e.g. firewall rules or allow_lists) that must be a map of CIDR/string to bool. If the raw YAML/JSON value is any other type (string, list, scalar), it returns "config `%s` has invalid type: %T" naming the key and the offending Go type, aborting config load.

Source

Thrown at allow_list.go:87

}

// If the handleKey func returns true, the rest of the parsing is skipped
// for this key. This allows parsing of special values like `interfaces`.
func newAllowListFromConfig(c *config.C, k string, handleKey func(key string, value any) (bool, error)) (*AllowList, error) {
	r := c.Get(k)
	if r == nil {
		return nil, nil
	}

	return newAllowList(k, r, handleKey)
}

// If the handleKey func returns true, the rest of the parsing is skipped
// for this key. This allows parsing of special values like `interfaces`.
func newAllowList(k string, raw any, handleKey func(key string, value any) (bool, error)) (*AllowList, error) {
	rawMap, ok := raw.(map[string]any)
	if !ok {
		return nil, fmt.Errorf("config `%s` has invalid type: %T", k, raw)
	}

	tree := new(bart.Table[bool])

	// Keep track of the rules we have added for both ipv4 and ipv6
	type allowListRules struct {
		firstValue     bool
		allValuesMatch bool
		defaultSet     bool
		allValues      bool
	}

	rules4 := allowListRules{firstValue: true, allValuesMatch: true, defaultSet: false}
	rules6 := allowListRules{firstValue: true, allValuesMatch: true, defaultSet: false}

	for rawCIDR, rawValue := range rawMap {
		if handleKey != nil {
			handled, err := handleKey(rawCIDR, rawValue)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Change the config key to a mapping of CIDR (or "0.0.0.0/0") to true/false, e.g. allow_lists: {local: {"10.0.0.0/8": true}}
  2. Fix YAML indentation so the value parses as a map, not a string or list
  3. Check for duplicate keys earlier in the file that override the intended mapping

Example fix

# before
allow_lists:
  local: 10.0.0.0/8
# after
allow_lists:
  local:
    10.0.0.0/8: true
Defensive patterns

Strategy: validation

Validate before calling

v, ok := rawCfg["allow_lists"]
if ok {
    if _, isMap := v.(map[string]any); !isMap {
        return errors.New("allow_lists must be a map of name -> {CIDR: bool}")
    }
}

Type guard

func isAllowListShape(raw any) bool {
    _, ok := raw.(map[string]any)
    return ok
}

Try / catch

al, err := newAllowListFromConfig(name, raw)
if err != nil {
    if strings.Contains(err.Error(), "has invalid type") {
        return fmt.Errorf("fix YAML: %s must be a mapping of CIDR to true/false: %w", name, err)
    }
    return err
}

Prevention

When it happens

Trigger: Defining an allow_list/firewall key as a scalar or array instead of a map — e.g. `allow_lists: local` or `groups: - a` shaped values passed into newAllowList from newAllowListFromConfig or getRemoteAllowRanges.

Common situations: YAML indentation mistakes collapsing a mapping into a scalar; putting a list where a map of CIDR->bool is required; accidental duplicate YAML keys overwriting a map with a string.

Related errors


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