<p>I am trying to update a label using kubectl v1.18.</p>
<p>I tried kubectl patch deployment my-deployment --patch &quot;$(cat patch1.yaml)&quot;; it returns an error</p>
<p>The Deployment &quot;my-deployment&quot; is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{&quot;app&quot;:&quot;nginx&quot;}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    client: user
  name:  my-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: revproxy
  strategy:
     type: RollingUpdate
     rollingUpdate:
       maxUnavailable: 1
       maxSurge: 2
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: revproxy
    spec:
      containers:
      - image: nginx:1.7.9
        name: nginx
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
</code></pre>
<p>The patch yaml is</p>
<pre><code>spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
</code></pre>

<p>From the docs <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#label-selector-updates" rel="nofollow noreferrer">here</a></p>
<blockquote>
<p>Note: In API version apps/v1, a Deployment's label selector is
immutable after it gets created.</p>
</blockquote>
<p>Motivations for making label selector immutable are</p>
<ol>
<li>Changing selectors leads to undefined behaviors - users are not expected to change the selectors</li>
<li>Having selectors immutable ensures they always match created children, preventing events such as accidental bulk orphaning</li>
</ol>
<p>If you want to make modification to label selector you will have to delete the exiting deployment and recreate it.</p>
<p>Modification to only <code>metadata.labels</code> should work though.</p>
