vitessio/vitess · error

rule %d: subjects list cannot include wildcard and other sub

Error message

rule %d: subjects list cannot include wildcard and other subjects, have %v

What it means

During RBAC config reification, subjects (users/groups, with "*" as an all-subjects wildcard) are validated per rule. A rule cannot combine "*" with named subjects because it would be redundant and ambiguous. Reify records a validation error with the rule index and the full subject list so the config author can fix it before vtadmin starts serving.

Source

Thrown at go/vt/vtadmin/rbac/config.go:101

	}

	// reify the rules
	byResource := map[string][]*Rule{}
	rec := concurrency.AllErrorRecorder{}

	for i, rule := range c.Rules {
		resourceRules := byResource[rule.Resource]

		actions := sets.New[string](rule.Actions...)
		if actions.Has("*") && actions.Len() > 1 {
			// error to have wildcard and something else
			rec.RecordError(fmt.Errorf("rule %d: actions list cannot include wildcard and other actions, have %v", i, sets.List(actions)))
		}

		subjects := sets.New[string](rule.Subjects...)
		if subjects.Has("*") && subjects.Len() > 1 {
			// error to have wildcard and something else
			rec.RecordError(fmt.Errorf("rule %d: subjects list cannot include wildcard and other subjects, have %v", i, sets.List(subjects)))
		}

		clusters := sets.New[string](rule.Clusters...)
		if clusters.Has("*") && clusters.Len() > 1 {
			// error to have wildcard and something else
			rec.RecordError(fmt.Errorf("rule %d: clusters list cannot include wildcard and other clusters, have %v", i, sets.List(clusters)))
		}

		resourceRules = append(resourceRules, &Rule{
			actions:  actions,
			subjects: subjects,
			clusters: clusters,
		})
		byResource[rule.Resource] = resourceRules
	}

	if rec.HasErrors() {
		return rec.Error()

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Use "*" alone for a catch-all rule.
  2. Or drop the wildcard and enumerate exactly the subjects allowed.
  3. If a rule must apply to everyone plus a group for other purposes, split into separate rules.

Example fix

// before
{"resource": "keyspaces", "actions": ["*"], "subjects": ["*", "admin@example.com"]}
// after
{"resource": "keyspaces", "actions": ["*"], "subjects": ["admin@example.com"]}
Defensive patterns

Strategy: validation

Validate before calling

for i, rule := range cfg.Rules {
	if slices.Contains(rule.Subjects, "*") && len(rule.Subjects) > 1 {
		return fmt.Errorf("rule %d: subjects must be * alone or explicit list", i)
	}
}

Type guard

func subjectsValid(subjects []string) bool {
	return !(slices.Contains(subjects, "*") && len(subjects) > 1)
}

Try / catch

rules, err := cfg.Reify()
if err != nil {
	log.Fatalf("fix RBAC subjects config: %v", err)
}

Prevention

When it happens

Trigger: RBAC config rule containing `subjects: ["*", "user@domain"]` or any wildcard subject plus named users/groups, then loading the config via config.Reify at vtadmin startup.

Common situations: Admin adds a named user to an already-wildcard rule intending to tighten it; merging rule sets from different environments; automated config generation that unions wildcards with lists.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/c1ad89d6e20b4594. Report an issue: GitHub.