logo

K8s Troubleshooting - "the object has been modified"

Error:

the object has been modified; please apply your changes to the latest version and try again

If you see this when manually applying a manifest

One possible cause is that you applied a dirty manifest (yaml), maybe previously dumped from an existing object, which contains fields such as creationTimestamp, resourceVersion, etc.

You can manually clean up the manifest, or use a command like this:

$ kubectl get KIND NAME -n NAMESPACE -o json | \
    jq "del(.status, .metadata.annotations, .metadata.creationTimestamp,
            .metadata.finalizers, .metadata.generation,
            .metadata.resourceVersion, .metadata.uid)" > object.json

If you see this in your controller

When you "Get" an object, the object has a resourceVersion inside ObjectMeta; if resourceVersion is changed before you submit your update, API server detects a diff in resourceVersion so it rejects your request.

Under the hood etcd stores a 64-bit int called revision for each object.

solution:

use RetryOnConflict

import (
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
  if _, err := controllerutil.CreateOrUpdate(ctx, client, object, func() error {
    // ...
    return nil
  }); err != nil {
    return err
  }
  return nil
})
if err != nil {
    return fmt.Errorf("failed to update object: %w", err)
}