[Bug]: PVC labels get inheritedMetadata on create, operator default on update

Author: GellertBabelCreated Sep 5, 2026Updated Sep 18, 2026
Labelsbug :bug:

Is there an existing issue already for this bug?

  • I have searched for an existing issue, and could not find anything. I believe this is a new bug.

I have read the troubleshooting guide

  • I have read the troubleshooting guide and I think this is a new bug.

I am running a supported version of CloudNativePG

  • I have read the troubleshooting guide and I think this is a new bug.

Contact Details

No response

Version

1.30.0

What version of Kubernetes are you using?

1.36

What is your Kubernetes environment?

Self-managed: kind (evaluation)

How did you install the operator?

YAML manifest

What happened?

If spec.inheritedMetadata.labels overrides one of the three common labels the operator sets on every PVC (app.kubernetes.io/name, app.kubernetes.io/managed-by, app.kubernetes.io/component), the PVC's label reconciler never settles. It keeps switching the label between the user's value and the operator's value, forever, on every reconcile.

I have observed it for app.kubernetes.io/name:

  1. PVC is created. Build() applies the operator default first, then inheritedMetadata last, so the PVC ends up with the user's value.
  2. At some point newLabelReconciler.update() runs on that PVC, for any reason. It applies inheritedMetadata first, then the operator default last, so the label flips to the operator's value.
  3. From then on, isUpToDate() keeps asking for the user's value (via cluster.GetFixedInheritedLabels()), but update() keeps writing the operator's value. Neither can win permanently against the other's check, so update() runs on every single reconcile of the cluster, indefinitely.

Create ends up with defaults-then-inheritance. Update ends up with inheritance-then-defaults. Every other object type CNPG manages applies inheritance last

Two code paths write the same three labels in opposite order relative to spec.inheritedMetadata.

pkg/reconciler/persistentvolumeclaim/build.go, Build(), runs once at PVC creation.

pkg/reconciler/persistentvolumeclaim/metadata.go, newLabelReconciler().update, runs on every reconcile after that.

isUpToDate(), just above update() in the same file, checks the PVC against cluster.GetFixedInheritedLabels() through IsLabelSubset, which still wants the user's value.

Cluster resource

bash
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: test
spec:
  instances: 1
  inheritedMetadata:
    labels:
      app.kubernetes.io/name: my-custom-app
  storage:
    size: 1Gi

Relevant log output

bash

Code of Conduct

  • I agree to follow this project's Code of Conduct

Source: cloudnative-pg/cloudnative-pg