slackhq/nebula · error

groups spec [%s] contains the group '"any". This rule will i

Error message

groups spec [%s] contains the group '"any". This rule will ignore the other groups specified

What it means

The special group name 'any' matches every group, so if it appears alongside other groups in one rule, the other groups are meaningless. The rule translator returns this error instead of silently ignoring the extra groups, forcing the author to write the rule unambiguously.

Source

Thrown at firewall.go:1027

	return r, nil
}

// sanity returns an error if the rule would be evaluated in a way that would short-circuit a configured check on a wildcard value
// rules are evaluated as "port AND proto AND (ca_sha OR ca_name) AND (host OR group OR groups OR cidr) AND local_cidr"
func (r *rule) sanity() error {
	//port, proto, local_cidr are AND, no need to check here
	//ca_sha and ca_name don't have a wildcard value, no need to check here
	groupsEmpty := len(r.Groups) == 0
	hostEmpty := r.Host == ""
	cidrEmpty := r.Cidr == ""

	if (groupsEmpty && hostEmpty && cidrEmpty) == true {
		return nil //no content!
	}

	groupsHasAny := slices.Contains(r.Groups, "any")
	if groupsHasAny && len(r.Groups) > 1 {
		return fmt.Errorf("groups spec [%s] contains the group '\"any\". This rule will ignore the other groups specified", r.Groups)
	}

	if r.Host == "any" {
		if !groupsEmpty {
			return fmt.Errorf("groups specified as %s, but host=any will match any host, regardless of groups", r.Groups)
		}

		if !cidrEmpty {
			return fmt.Errorf("cidr specified as %s, but host=any will match any host, regardless of cidr", r.Cidr)
		}
	}

	if groupsHasAny {
		if !hostEmpty && r.Host != "any" {
			return fmt.Errorf("groups spec [%s] contains the group '\"any\". This rule will ignore the specified host %s", r.Groups, r.Host)
		}
		if !cidrEmpty {
			return fmt.Errorf("groups spec [%s] contains the group '\"any\". This rule will ignore the specified cidr %s", r.Groups, r.Cidr)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Remove 'any' and keep only the explicit groups if you want them to match
  2. Or use groups: ['any'] alone if you truly want to match any group
  3. Note that semantically the rule already behaves as any-group; just clean the config

Example fix

// before
groups: [any, prod]
// after
groups: [any]
Defensive patterns

Strategy: validation

Validate before calling

func checkAnyGroup(groups []string) error {
    if slices.Contains(groups, "any") && len(groups) > 1 {
        return fmt.Errorf("groups contains 'any' plus other groups: %v", groups)
    }
    return nil
}

Type guard

func isUnambiguousGroups(groups []string) bool {
    return !(slices.Contains(groups, "any") && len(groups) > 1)
}

Try / catch

if err := loadFirewallConfig(cfg); err != nil {
    if strings.Contains(err.Error(), "contains the group") {
        return fmt.Errorf("groups=any conflicts with other selectors: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: A firewall rule whose groups list contains 'any' plus at least one other group, e.g. groups: ['any', 'prod'], during rule translation.

Common situations: Author assuming groups are ORed and trying to widen a rule by adding 'any'; templating that appends 'any' to an existing list.

Related errors


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