istio/istio · error

cannot create revision tag %q: found existing control plane

Error message

cannot create revision tag %q: found existing control plane revision with same name

What it means

checkTagDuplicate refuses to create a revision tag whose name collides with an existing control plane revision: it lists services labeled with the tag revision in the istio namespace (GetServicesWithRevision) and webhook configurations selecting that revision (GetWebhooksWithRevision); if either returns matches, the tag cannot be created because `istio.io/rev=<tag>` labels would route traffic to both. Note the earlier `checkControlPlaneExistenceOrDuplicate` nil-return quirk: it returns nil (no error) when the canonical revision does NOT exist, and this duplicate check is the hard guard for tag/rev collisions.

Source

Thrown at istioctl/pkg/tag/generate.go:186

func checkTagNameCollidesWithRevisionName(
	ctx context.Context,
	client kubernetes.Interface,
	opts *GenerateOptions,
) error {
	if opts.Generate || opts.Overwrite || opts.Tag == DefaultRevisionName {
		return nil
	}
	revServiceCollisions, err := GetServicesWithRevision(ctx, client, opts.IstioNamespace, opts.Tag)
	if err != nil {
		return err
	}
	// abort if there exists a revision with the target tag name
	revWebhookCollisions, err := GetWebhooksWithRevision(ctx, client, opts.Tag)
	if err != nil {
		return err
	}
	if len(revWebhookCollisions) > 0 || len(revServiceCollisions) > 0 {
		return fmt.Errorf("cannot create revision tag %q: found existing control plane revision with same name", opts.Tag)
	}
	return nil
}

func checkControlPlaneExistenceOrDuplicate(
	ctx context.Context,
	client kubernetes.Interface,
	opts *GenerateOptions,
) (*admitv1.MutatingWebhookConfiguration, error) {
	revServices, err := GetServicesWithRevision(ctx, client, opts.IstioNamespace, opts.Revision)
	if err != nil {
		return nil, err
	}

	if len(revServices) > 1 {
		return nil, fmt.Errorf("cannot modify tag: found multiple canonical services with revision %q in namespace %q", opts.Revision, opts.IstioNamespace)
	}
	revWebhooks, err := GetWebhooksWithRevision(ctx, client, opts.Revision)

View on GitHub (pinned to 8dc789c5cf)

Solutions

  1. Pick a different tag name that matches no existing revision.
  2. Or clean up the colliding artifacts: delete the leftover `istiod-<tag>` service and webhook configuration, then retry.
  3. List current revisions: `istioctl revision list` or `kubectl get svc,mutatingwebhookconfiguration -l istio.io/rev -n istio-system`.

Example fix

# before
istioctl tag set canary --revision 1-20  # a revision named 'canary' exists

# after
istioctl tag set prod-canary --revision 1-20
Defensive patterns

Strategy: validation

Validate before calling

# pre-check for name collisions before tag set
COLLIDE=$(kubectl -n istio-system get svc,mutatingwebhookconfiguration -l istio.io/rev="$TAG" -o name 2>/dev/null)
[ -z "$COLLIDE" ] || { echo "tag '$TAG' already names a revision" >&2; exit 2; }
istioctl tag set "$TAG" --revision "$REV"

Prevention

When it happens

Trigger: `istioctl tag set mytag --revision myrev` where a revision literally named `mytag` already exists — i.e. there is already an istiod service `istiod-mytag` or a webhook configuration for revision `mytag`.

Common situations: Choosing a tag name equal to an existing revision (e.g. tagging `default` when a revision named `default` exists, or `stable` when `istiod-stable` is deployed); leftovers from a removed tag whose webhook/service were not cleaned up.

Related errors


AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15). Data as JSON: /api/errors/b074e0e129814085. Report an issue: GitHub.