kubernetes/kops · error

Found multiple role tags: %q vs %q

Error message

Found multiple role tags: %q vs %q

What it means

Raised while computing the role from ASG tags in the Terraform render path: the ASG carries more than one kops instance-group role tag (prefix k8s.io/cluster-autoscaler/... role prefix) with conflicting role suffixes. kops uses this tag to link the ASG to a role and refuses ambiguous configurations.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/autoscalinggroup.go:1014

		}
	} else if e.LaunchTemplate != nil {
		tf.LaunchTemplate = &terraformAutoscalingLaunchTemplateSpecification{
			LaunchTemplateID: e.LaunchTemplate.TerraformLink(),
			Version:          e.LaunchTemplate.VersionLink(),
		}
	} else {
		return fmt.Errorf("could not find one of launch configuration, mixed instances policy, or launch template")
	}

	role := ""
	for k := range e.Tags {
		if strings.HasPrefix(k, CloudTagInstanceGroupRolePrefix) {
			suffix := strings.TrimPrefix(k, CloudTagInstanceGroupRolePrefix)
			if suffix == "control-plane" {
				suffix = "master"
			}
			if role != "" && role != suffix {
				return fmt.Errorf("Found multiple role tags: %q vs %q", role, suffix)
			}
			role = suffix
		}
	}

	if e.LaunchTemplate != nil && role != "" {
		for _, sg := range e.LaunchTemplate.SecurityGroups {
			if err := t.AddOutputVariableArray(role+"_security_group_ids", sg.TerraformLink()); err != nil {
				return err
			}
		}
	}
	if role != "" {
		if err := t.AddOutputVariableArray(role+"_autoscaling_group_ids", e.TerraformLink()); err != nil {
			return err
		}
	}
	if role == "node" {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect ASG tags (`aws autoscaling describe-tags --filters Name=resource-id,Values=<asg-name>`) and remove the conflicting role tag so only one remains.
  2. Re-apply with kops so desired tags are reconciled after manual cleanup.
  3. If the ASG genuinely serves two roles, split it into separate instance groups with one role tag each.
  4. Check the cluster spec cloudLabels/instance group role configuration for accidental duplicates.

Example fix

// before: two role tags on one ASG
k8s.io/role/node: "1"
k8s.io/role/bastion: "1"
// after: keep only the matching role
k8s.io/role/node: "1"
Defensive patterns

Strategy: validation

Validate before calling

// pre-check ASG role tags for conflicts
roles := map[string]bool{}
for k := range asgTags {
  if strings.HasPrefix(k, "k8s.io/role/") {
    roles[strings.TrimPrefix(k, "k8s.io/role/")] = true
  }
}
if len(roles) > 1 { return fmt.Errorf("ASG %s has conflicting role tags: %v", name, roles) }

Try / catch

if err := render(); err != nil {
  if strings.Contains(err.Error(), "Found multiple role tags") {
    return fmt.Errorf("clean duplicate k8s.io/role/* tags on the ASG, then re-apply: %w", err)
  }
  return err
}

Prevention

When it happens

Trigger: Iterating e.Tags, two tags with the CloudTagInstanceGroupRolePrefix yield different suffixes (e.g. .../role/node vs .../role/bastion) on the same ASG task.

Common situations: Manually copied tags between ASGs; a cluster rename left old role tags alongside new ones; a script added per-role tags to a shared ASG; merging instance groups left stale tags.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/ea81976fa1a78073. Report an issue: GitHub.