derailed/k9s · error

revision conversion failed

Error message

revision conversion failed

What it means

getRSRevision reads the annotation "deployment.kubernetes.io/revision" off a ReplicaSet and converts it with strconv.Atoi to build the rollback target revision. If the annotation is absent (Atoi receives ""), empty, or non-numeric, conversion fails. Only ReplicaSets managed by the Deployment controller carry this annotation, so unmanaged or externally-created RSes hit this path.

Source

Thrown at internal/dao/rs.go:66

	}

	var rs appsv1.ReplicaSet
	err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &rs)
	if err != nil {
		return nil, err
	}

	return &rs, nil
}

func getRSRevision(rs *appsv1.ReplicaSet) (int64, error) {
	revision := rs.Annotations["deployment.kubernetes.io/revision"]
	if rs.Status.Replicas != 0 {
		return 0, errors.New("can not rollback current replica")
	}
	vers, err := strconv.Atoi(revision)
	if err != nil {
		return 0, errors.New("revision conversion failed")
	}

	return int64(vers), nil
}

func controllerInfo(rs *appsv1.ReplicaSet) (name, kind, group string, err error) {
	for _, ref := range rs.OwnerReferences {
		if ref.Controller == nil {
			continue
		}
		group, tokens := ref.APIVersion, strings.Split(ref.APIVersion, "/")
		if len(tokens) == 2 {
			group = tokens[0]
		}
		return ref.Name, ref.Kind, group, nil
	}

	return "", "", "", fmt.Errorf("unable to find controller for replicaset: %s", rs.Name)

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Verify the annotation exists and is numeric: kubectl get rs <name> -o jsonpath='{.metadata.annotations.deployment\.kubernetes\.io/revision}'.
  2. Only run rollback on ReplicaSets owned by a Deployment (check ownerReferences).
  3. If the annotation was lost, recreate the RS from the Deployment or restore it with `kubectl annotate rs <name> deployment.kubernetes.io/revision=<n>` before retrying.

Example fix

// before: rollback attempted on an RS lacking the annotation
rs.Annotations["deployment.kubernetes.io/revision"] == "" -> strconv.Atoi("") fails
// after: guard before calling Rollback
if rev, ok := rs.Annotations["deployment.kubernetes.io/revision"]; !ok || rev == "" {
    return fmt.Errorf("rs %s has no revision annotation; not deployment-managed", rs.Name)
}
Defensive patterns

Strategy: validation

Validate before calling

rev, ok := rs.Annotations["deployment.kubernetes.io/revision"]
if !ok || rev == "" {
    return fmt.Errorf("rs %s lacks revision annotation (not deployment-managed)", rs.Name)
}
if _, err := strconv.Atoi(rev); err != nil {
    return fmt.Errorf("rs %s has non-numeric revision %q", rs.Name, rev)
}

Prevention

When it happens

Trigger: Invoking :rollback on a ReplicaSet that has no deployment.kubernetes.io/revision annotation (standalone RS, created by another controller, hand-applied YAML); the annotation value was edited to a non-numeric string.

Common situations: ReplicaSets created by tools that do not set the revision annotation; CRD-based or custom controllers that spawn RSes; manifest templates that strip annotations; version drift after cluster migrations that lose annotations.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/351fea5655d3a3df. Report an issue: GitHub.