<p>I'm trying to remove a key/value pair from an existing deployment's <code>spec.selector.matchLabels</code> config. For example, I'm trying to remove the <code>some.old.label: blah</code> label from <code>spec.selector.matchLabels</code> and <code>spec.template.metadata.labels</code>. So this is an excerpt of what I'm sending to <code>kubectl apply -f</code>:</p>
<pre class="lang-yaml prettyprint-override"><code>    spec:
      selector:
        matchLabels:
          app: my-app
      template:
        metadata:
          labels:
            app: my-app
</code></pre>
<p>but that gives me the following error:</p>
<blockquote>
<p><code>selector</code> does not match template <code>labels</code></p>
</blockquote>
<p>I also tried <code>kubectl replace</code>, which gives me this error:</p>
<blockquote>
<p>v1.LabelSelector{MatchLabels:map[string]string{“app”: &quot;my-app&quot;}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable</p>
</blockquote>
<p>which makes sense once I checked the deployment's config in prod:</p>
<pre class="lang-yaml prettyprint-override"><code>metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
       # my config is trying to mutate the matchLabels here:
       {&quot;apiVersion&quot;:&quot;apps/v1&quot;, ... &quot;selector&quot;:{&quot;matchLabels&quot;:{&quot;app&quot;:&quot;my-app&quot;} ... }
  # etc...
spec:
  selector:
    matchLabels:
      app: my-app
      some.old.label: blah  # how do I remove this label from both the metadata.labels and matchLabels?
  template:
    metadata:
      labels:
        app: my-app
        some.old.label: blah # I want to remove this label
</code></pre>
<p>Notice how the <code>some.old.label: blah</code> key/value is set under <code>selector.matchLabels</code> and  <code>template.metadata.labels</code>.</p>
<p>Will I have to delete-then-recreate my deployment? Or perhaps call <code>kubectl replace --force</code>?</p>
<h3>Notes</h3>
<p>I came across this section in the <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#label-selector-updates" rel="nofollow noreferrer">Kubernetes Deployment docs</a>:</p>
<blockquote>
<p>Selector removals removes an existing key from the Deployment selector -- do not require any changes in the Pod template labels. Existing ReplicaSets are not orphaned, and a new ReplicaSet is not created, but note that the removed label still exists in any existing Pods and ReplicaSets.</p>
</blockquote>
<p>as well as <a href="https://github.com/kubernetes/website/pull/3877" rel="nofollow noreferrer">this PR</a> and <a href="https://github.com/kubernetes/kubernetes/issues/50808" rel="nofollow noreferrer">this Github issue</a> which speak about the reasoning behind the problem, but I can't figure out <em>how</em> I'm can safely update my deployment to remove this selector.</p>

<p>When the error message says &quot;field is immutable&quot;, it means you can't change it once it's been set.  You need to delete and recreate the Deployment with the label selector you want (which will also temporarily delete all of the matching Pods).</p>
<pre class="lang-sh prettyprint-override"><code>kubectl delete deployment my-app
kubectl apply -f ./deployment.yaml
</code></pre>
