Kubernetes Service invalid clusterIP or resourceVersion

Kubernetes is a great service, but doesn't help Google image of building terrible interfaces and experiences in their engineering tools. A perfect example of this is when you attempt to modify a Service in Kubernetes that you already created and applied some updates to and are greeted by the following error:

✗ kubectl apply -f .kube/service.yaml
The Service "my-service" is invalid:
* metadata.resourceVersion: Invalid value: "": must be specified for an update
* spec.clusterIP: Invalid value: "": field is immutable

This error tells you two things:

  1. You must have spec.clusterIP defined
  2. You must have metadata.resourceVersion defined

The only problem with this error is that it's not true and encourages storing information that may change in your Service definition file. The resourceVersion will change with every modification to the service, and while the clusterIP may not, that's still not data you should have in your Service definition.

The cause of this problem ends up being the kubectl.kubernetes.io/last-applied-configuration annotation. If you ever deploy with one of those two values, or even want to drop a label from your Service and don't explicitly set it to null in your next deploy, you will get this cryptic error.

In order to reset your Service so you can deploy with a clean definition file again, just remove the kubectl.kubernetes.io/last-applied-configuration annotation by running

kubectl annotate svc my-service kubectl.kubernetes.io/last-applied-configuration-

The - on the end of the annotation tells Kubernetes to remove the annotation entirely.

You should now be free to kubectl apply updates to your service again!