Skip to content
Release Radar

CloudNativePG

Databases

PostgreSQL operator for Kubernetes

v1.30.1same day as v1.29.3
View on GitHub

Part of Databases

Release history

v1.30.1

CompareGitHub

Release date: Sep 23, 2026

Enhancements

  • Added restoreAdditionalCommandArgs to .barmanObjectStore.data for in-tree Barman Cloud recoveries, so custom flags are forwarded to barman-cloud-restore during recovery. (#11278) <!-- 1.29 1.28 -->

  • Plugin authors no longer need to re-derive whether an empty WAL archive should be treated as an error: the operator now computes the check_empty_wal_archive decision once and passes it to CNPG-I plugins on both WAL archiving and restore hooks. (#11216) <!-- 1.29 1.28 -->

  • Allowed setting the ssl_ecdh_curve PostgreSQL parameter in .spec.postgresql.parameters. It was previously rejected by the validating webhook even though the operator does not manage it. Contributed by @Jamstah. (#11308) <!-- 1.29 1.28 -->

  • Added support for setting auth_user in spec.pgbouncer.parameters to override the user PgBouncer uses for its auth_query connection, instead of always deriving it from the authQuerySecret. Useful with a custom authQuerySecret where the role to authenticate as differs from the one implied by the Secret. Contributed by @jonasbadstuebner. (#10899) <!-- 1.29 1.28 -->

  • Fixed PgBouncer metrics silently reporting zero when PgBouncer adds or reorders columns: SHOW STATS and SHOW POOLS results are now matched by column name instead of by position. Contributed by @AdzerKI (SHOW STATS). (#11366, #11464) <!-- 1.29 1.28 -->

  • cnpg plugin:

    • Added a --dry-run option to the backup command that prints the Backup resource that would be created, without creating it. (#11233) <!-- 1.29 1.28 -->

Security and Supply Chain

  • Fixed a webhook validation bypass where an absolute extension path with an embedded .. traversal (e.g. /a/../../../../etc) was accepted because only the raw path was checked; such paths still escaped the extension's mount point once resolved at runtime. Affected entries are now resolved and rejected/skipped consistently across admission, the major-upgrade job, and already-persisted Cluster specs. Contributed by @Anand-240. (#11210) <!-- 1.29 1.28 -->

  • Updated google.golang.org/grpc to v1.83.1, fixing CVE-2026-84304 / GHSA-vp52-pcj8-j9qc (gRPC-Go heap memory exhaustion via HTTP/2 DATA frame fragmentation). (#11394) <!-- 1.29 1.28 -->

Changes

  • Updated the default PostgreSQL operand image to 18.6-system-trixie. (#11257) <!-- 1.29 1.28 -->

  • Moved the operator's own base image from Debian 12 (bookworm) to Debian 13 (trixie), now that Debian 12 has moved to LTS-only maintenance. (#11193) <!-- 1.29 1.28 -->

Fixes

  • Demoted an unreachable old primary immediately during failover, instead of waiting on checkpoint and fast-shutdown attempts that could never complete. Previously, an old primary whose PostgreSQL had become unresponsive was never shut down, so it could never rejoin the cluster as a replica of the new primary. The shutdown is now requested without blocking the reconciler, though demotion can still take up to a minute or more if PostgreSQL keeps ignoring shutdown signals. (#11347) <!-- 1.29 1.28 -->

  • Fixed failover and Pod recreation getting stuck while any instance in the cluster was fenced. A fenced instance kept reporting itself as healthy on its status endpoint even though its Pod was permanently not Ready, which blocked the readiness guard, the primary-election logic, and the Pod-reattachment gate from reacting to an unrelated failure elsewhere in the cluster, leaving it stalled until someone manually removed the fencing. All three now recognize and skip fenced instances. (#11274) <!-- 1.29 1.28 -->

  • Fixed a failover that could stall forever or get silently reverted. While a failover was pending, the reconciler could skip checking whether it was ready to complete, or mistake the pending state for a missing Pod and reset the target primary back to the unhealthy one. It now keeps progressing a pending failover and completes it once the WAL receivers are down, rechecking quorum safety right before promoting in case it changed while waiting. (#11336) <!-- 1.29 1.28 -->

  • Fixed the designated-primary sort in PostgresqlStatusList so a tie on LSN no longer sorts it out of order. If the designated primary's Pod later disappeared from the status list, this could have led the operator to promote the wrong standby. (#11494) <!-- 1.29 1.28 -->

  • Gated PostgreSQL startup on the instance manager actually holding the primary Lease, closing a window where a restarting or rescheduled primary could start accepting writes before acquiring the lease. Lease acquisition now happens during instance initialization, strictly before PostgreSQL is allowed to start, instead of only later in the reconciliation loop once the instance was already reported ready. (#11356)

  • Bounded the primary lease take-over Get call to the lease's RenewDeadline, so a call against an unreachable API server now fails fast and retries instead of blocking indefinitely. Left unbounded, the same stalled call could also delay a primary's own lease renewal after a transient API server blip, risking an unwanted takeover by another instance once the lease appeared to expire. (#11350)

  • Stopped abandoning a fast shutdown after 60 seconds. The request carried no explicit timeout, so pg_ctl fell back to its own implicit 60-second limit, and the instance manager, being PID 1 in the container, took PostgreSQL down mid-shutdown regardless of a larger configured stopDelay. The fast phase now waits for the full stopDelay instead. (#11263) <!-- 1.29 1.28 -->

  • Waited for certificate status before refreshing secrets during bootstrap. (#11450) <!-- 1.29 1.28 -->

  • Fixed in-tree Barman Cloud recovery ignoring wal.maxParallel and wal.restoreAdditionalCommandArgs, fetching WAL one segment at a time instead of using the configured parallelism. (#11105) <!-- 1.29 1.28 -->

  • Honored the unrecoverable annotation on pending and terminating instances. (#11241) <!-- 1.29 1.28 -->

  • Honored Backup.spec.online when finalizing VolumeSnapshot-based backups, so a cold backup is no longer reported as online in status. (#11276) <!-- 1.29 1.28 -->

  • Set --no-data-checksums explicitly when .spec.postgresql.dataChecksums is false on PostgreSQL 18+, which now enables checksums by default in initdb. Contributed by @evan314159. (#11488) <!-- 1.29 1.28 -->

  • Stopped discarding .spec.inheritedMetadata labels on PVC reconciliation; they were applied before, and then overwritten by, the operator's own labels. Contributed by @GellertBabel. (#11499) <!-- 1.29 1.28 -->

  • Stopped Pooler and DatabaseRole from recreating their owned resources after being marked for deletion, which could block an external finalizer (e.g. ArgoCD foreground deletion) waiting for those resources to disappear. Contributed by @mjlshen. (#11359) <!-- 1.29 1.28 -->

  • Handled a NULL stats_reset value in the pg_stat_wal metric, which could occasionally break Prometheus scraping on PostgreSQL 18 clusters. Contributed by @HoniSanders. (#11207) <!-- 1.29 1.28 -->

  • Recovered log streaming when a stale non-FIFO file blocked the log pipe. (#11246) <!-- 1.29 1.28 -->

  • Stopped sampling logs of the Pods' processes, so no log lines are silently dropped. (#11131) <!-- 1.29 1.28 -->

  • Stopped caching Helm release Secrets in the operator, which could spike memory usage and crashloop the operator on clusters with large Helm releases installed alongside it. (#11211) <!-- 1.29 1.28 -->

  • Re-ran owned-resource finalizer cleanup after an operator restart, so a namespace deleted while the operator was down doesn't hang in Terminating forever. (#11215) <!-- 1.29 1.28 -->

  • Fixed rejoining replicas taking a long time to complete pg_rewind when WAL prefetching (wal.maxParallel > 1) was enabled. (#11204) <!-- 1.29 1.28 -->

  • Treated a PostgreSQL instance rejecting connections as started up in p

…(truncated)

Release date: Sep 23, 2026

:::warning This is the final release in the 1.29.x series. Users are strongly encouraged to upgrade to a newer minor version, as 1.29 is no longer supported. :::

Enhancements

  • Added restoreAdditionalCommandArgs to .barmanObjectStore.data for in-tree Barman Cloud recoveries, so custom flags are forwarded to barman-cloud-restore during recovery. (#11278) <!-- 1.29 1.28 -->

  • Plugin authors no longer need to re-derive whether an empty WAL archive should be treated as an error: the operator now computes the check_empty_wal_archive decision once and passes it to CNPG-I plugins on both WAL archiving and restore hooks. (#11216) <!-- 1.29 1.28 -->

  • Allowed setting the ssl_ecdh_curve PostgreSQL parameter in .spec.postgresql.parameters. It was previously rejected by the validating webhook even though the operator does not manage it. Contributed by @Jamstah. (#11308) <!-- 1.29 1.28 -->

  • Added support for setting auth_user in spec.pgbouncer.parameters to override the user PgBouncer uses for its auth_query connection, instead of always deriving it from the authQuerySecret. Useful with a custom authQuerySecret where the role to authenticate as differs from the one implied by the Secret. Contributed by @jonasbadstuebner. (#10899) <!-- 1.29 1.28 -->

  • Fixed PgBouncer metrics silently reporting zero when PgBouncer adds or reorders columns: SHOW STATS and SHOW POOLS results are now matched by column name instead of by position. Contributed by @AdzerKI (SHOW STATS). (#11366, #11464) <!-- 1.29 1.28 -->

  • cnpg plugin:

    • Added a --dry-run option to the backup command that prints the Backup resource that would be created, without creating it. (#11233) <!-- 1.29 1.28 -->

Security and Supply Chain

  • Fixed a webhook validation bypass where an absolute extension path with an embedded .. traversal (e.g. /a/../../../../etc) was accepted because only the raw path was checked; such paths still escaped the extension's mount point once resolved at runtime. Affected entries are now resolved and rejected/skipped consistently across admission, the major-upgrade job, and already-persisted Cluster specs. Contributed by @Anand-240. (#11210) <!-- 1.29 1.28 -->

  • Updated google.golang.org/grpc to v1.83.1, fixing CVE-2026-84304 / GHSA-vp52-pcj8-j9qc (gRPC-Go heap memory exhaustion via HTTP/2 DATA frame fragmentation). (#11394) <!-- 1.29 1.28 -->

Changes

  • Updated the default PostgreSQL operand image to 18.6-system-trixie. (#11257) <!-- 1.29 1.28 -->

  • Moved the operator's own base image from Debian 12 (bookworm) to Debian 13 (trixie), now that Debian 12 has moved to LTS-only maintenance. (#11193) <!-- 1.29 1.28 -->

Fixes

  • Demoted an unreachable old primary immediately during failover, instead of waiting on checkpoint and fast-shutdown attempts that could never complete. Previously, an old primary whose PostgreSQL had become unresponsive was never shut down, so it could never rejoin the cluster as a replica of the new primary. The shutdown is now requested without blocking the reconciler, though demotion can still take up to a minute or more if PostgreSQL keeps ignoring shutdown signals. (#11347) <!-- 1.29 1.28 -->

  • Fixed failover and Pod recreation getting stuck while any instance in the cluster was fenced. A fenced instance kept reporting itself as healthy on its status endpoint even though its Pod was permanently not Ready, which blocked the readiness guard, the primary-election logic, and the Pod-reattachment gate from reacting to an unrelated failure elsewhere in the cluster, leaving it stalled until someone manually removed the fencing. All three now recognize and skip fenced instances. (#11274) <!-- 1.29 1.28 -->

  • Fixed a failover that could stall forever or get silently reverted. While a failover was pending, the reconciler could skip checking whether it was ready to complete, or mistake the pending state for a missing Pod and reset the target primary back to the unhealthy one. It now keeps progressing a pending failover and completes it once the WAL receivers are down, rechecking quorum safety right before promoting in case it changed while waiting. (#11336) <!-- 1.29 1.28 -->

  • Fixed the designated-primary sort in PostgresqlStatusList so a tie on LSN no longer sorts it out of order. If the designated primary's Pod later disappeared from the status list, this could have led the operator to promote the wrong standby. (#11494) <!-- 1.29 1.28 -->

  • Stopped abandoning a fast shutdown after 60 seconds. The request carried no explicit timeout, so pg_ctl fell back to its own implicit 60-second limit, and the instance manager, being PID 1 in the container, took PostgreSQL down mid-shutdown regardless of a larger configured stopDelay. The fast phase now waits for the full stopDelay instead. (#11263) <!-- 1.29 1.28 -->

  • Waited for certificate status before refreshing secrets during bootstrap. (#11450) <!-- 1.29 1.28 -->

  • Fixed in-tree Barman Cloud recovery ignoring wal.maxParallel and wal.restoreAdditionalCommandArgs, fetching WAL one segment at a time instead of using the configured parallelism. (#11105) <!-- 1.29 1.28 -->

  • Honored the unrecoverable annotation on pending and terminating instances. (#11241) <!-- 1.29 1.28 -->

  • Honored Backup.spec.online when finalizing VolumeSnapshot-based backups, so a cold backup is no longer reported as online in status. (#11276) <!-- 1.29 1.28 -->

  • Retried volume snapshot backups on transient instance-manager connection errors (e.g. a dial timeout from a brief pod-network disruption), instead of failing the backup outright. (#11069) <!-- 1.29 1.28 -->

  • Set --no-data-checksums explicitly when .spec.postgresql.dataChecksums is false on PostgreSQL 18+, which now enables checksums by default in initdb. Contributed by @evan314159. (#11488) <!-- 1.29 1.28 -->

  • Stopped discarding .spec.inheritedMetadata labels on PVC reconciliation; they were applied before, and then overwritten by, the operator's own labels. Contributed by @GellertBabel. (#11499) <!-- 1.29 1.28 -->

  • Stopped Pooler and DatabaseRole from recreating their owned resources after being marked for deletion, which could block an external finalizer (e.g. ArgoCD foreground deletion) waiting for those resources to disappear. Contributed by @mjlshen. (#11359) <!-- 1.29 1.28 -->

  • Handled a NULL stats_reset value in the pg_stat_wal metric, which could occasionally break Prometheus scraping on PostgreSQL 18 clusters. Contributed by @HoniSanders. (#11207) <!-- 1.29 1.28 -->

  • Recovered log streaming when a stale non-FIFO file blocked the log pipe. (#11246) <!-- 1.29 1.28 -->

  • Stopped sampling logs of the Pods' processes, so no log lines are silently dropped. (#11131) <!-- 1.29 1.28 -->

  • Stopped caching Helm release Secrets in the operator, which could spike memory usage and crashloop the operator on clusters with large Helm releases installed alongside it. (#11211) <!-- 1.29 1.28 -->

  • Re-ran owned-resource finalizer cleanup after an operator restart, so a namespace deleted while the operator was down doesn't hang in Terminating forever. (#11215) <!-- 1.29 1.28 -->

  • Fixed rejoining replicas taking a long time to complete pg_rewind when WAL prefetching (wal.maxParallel > 1) was enabled. (#11204) <!-- 1.29 1.28 -->

  • Treated a PostgreSQL instance rejecting connections as started up in probes. (#11152) <!-- 1.29 1.28 -->

  • Stopped issuing a redundant PATCH on every reconciliation when a cluster's pvcTemplate set volumeAttributesClass. Contributed by @andrew-farries. (#11196) <!-- 1.29 1.28 -->

  • Stopped halting replication slot reconciliation at the first failing slot. (#11119) <!-- 1.29 1.28

…(truncated)

Release date: Jun 29, 2026

Important changes

  • Updated the deprecation notice for native (in-tree) Barman Cloud support to reflect that it will now be removed in CloudNativePG 1.31.0, rather than 1.30.0. Users are still encouraged to migrate to the Barman Cloud Plugin. (#11083) <!-- 1.29 1.28 -->

  • The cluster reference is now immutable on the Database, Pooler, Publication, Subscription, and ScheduledBackup resources. Pointing one of these objects at a different cluster has no well-defined semantics and previously left the controllers in an inconsistent state; the update is now rejected at the API server via a CEL validation rule. (#10743) <!-- 1.29 1.28 1.25 -->

Features

  • Primary Lease for safe primary election: introduced a Kubernetes Lease object (named after the cluster) that acts as a mutex serializing primary promotion: the instance manager must hold the lease before acting as primary and releases it on clean shutdown so replicas can promote without waiting for the full TTL. Timings are configurable via the new .spec.primaryLease stanza. The lease is a promotion gate, not a fence. Primary isolation remains responsible for fencing. (#10627)

  • DatabaseRole CRD for declarative role management: introduced a DatabaseRole custom resource that manages a PostgreSQL role as a standalone Kubernetes object, instead of declaring it inline in the Cluster's .spec.managed.roles stanza. Each role gets its own lifecycle, status, and RBAC, which suits GitOps workflows and lets role definitions live next to the applications that own them. The spec reuses the same RoleConfiguration structure as the inline method, so migrating a role is a matter of moving the stanza into its own manifest. A databaseRoleReclaimPolicy field (retain, the default, or delete) controls what happens to the role when the resource is deleted, mirroring persistent volumes. (#6155)

  • TLS client certificates for declarative roles: a DatabaseRole can now include a clientCertificate block to have the operator automatically generate and renew a TLS client certificate, signed by the cluster's client CA and stored in a <databaserole-name>-client-cert Secret. This enables password-free PostgreSQL cert authentication; the Secret is cleaned up when the feature is disabled or the DatabaseRole is deleted. (#10896)

  • PgBouncer image management via image catalogs: the Pooler resource can now reference an entry in an ImageCatalog or ClusterImageCatalog through the new spec.pgbouncer.imageCatalogRef field, centralizing PgBouncer image management. When a catalog entry is updated, all referencing Poolers are automatically reconciled and roll out the new image without any change to their spec. The resolved image is reported in status.image, and a new status.phase (active, paused, inactive, or failed), also surfaced as a Phase column in kubectl get pooler, summarizes the lifecycle. (#10568)

Enhancements

  • Enabled pg_upgrade in-place major upgrades to PostgreSQL 19 or later for clusters that use Image Volume extensions, building on the extension-path support added to pg_upgrade in PostgreSQL 19. During the upgrade Job, the source- and target-version extension images are mounted side by side, so the old server keeps its libraries and a failed upgrade reverts cleanly. (#10366) <!-- 1.29 -->

  • Added TLS support for the Pooler metrics endpoint via .spec.monitoring.tls.enabled. When enabled, the metrics server is served over HTTPS, reusing the certificate and key from .spec.pgbouncer.clientTLSSecret and reloading it on every handshake to support rotation without a restart; the generated PodMonitor scrapes over https accordingly. (#10466)

  • Added a label selector to the Cluster scale subresource (status.selector), making a Cluster a valid targetRef for the Vertical Pod Autoscaler (VPA) and Horizontal Pod Autoscaler (HPA), which can now map a Cluster to its instance pods. Contributed by @sebv004. (#8996) <!-- 1.29 1.28 1.25 -->

  • The operator now emits a Warning PrimaryStatusCheckFailed event on the Cluster when the primary pod is Ready from the kubelet perspective but the operator's /pg/status check fails and failover is deferred, giving users visibility into the deferral via kubectl describe cluster. (#10509) <!-- 1.29 1.28 1.25 -->

  • Added the ENABLE_WEBHOOK_NAMESPACE_SUFFIX flag, which suffixes the operator's webhook configuration names with -<OPERATOR_NAMESPACE> so that multiple operator instances can coexist on the same cluster. The operator only looks up these configurations; users must create and maintain them. Contributed by @maxlengdell. (#10420) <!-- 1.29 1.28 1.25 -->

  • The operator now reloads a CNPG-i plugin automatically when its pods are rolled: it watches the EndpointSlices backing plugin Services and re-enqueues every cluster using the plugin once the new pods become Ready, so an upgraded plugin is picked up without waiting for the next resync. (#10836) <!-- 1.29 1.28 1.25 -->

  • Instance serial numbers are now assigned by reusing the lowest free slot among existing instance names, instead of always incrementing a global counter. Pod and PVC names stay stable across instance recreation (for example, an instance recreated after a node drain comes back with the same name), and serials freed by deleted instances are reclaimed. A new Initialized cluster condition reports whether the cluster has completed its first bootstrap, and status.latestGeneratedNode is deprecated: it is no longer written, but is preserved on the CRD for backward compatibility. (#10548)

  • Defaulting and validation now run during reconciliation as a fallback when admission webhooks are unavailable, or configured to ignore failures, so the operator no longer reconciles invalid or incomplete specs. Missing defaults are applied directly, and validation failures are surfaced in the resource status instead of failing silently later. (#10874)

Security

  • CVE-2026-55769 / GHSA-x8c2-3p4r-v9r6: search_path pinning on operator-issued connections: a database owner could plant overloaded built-in operators in the public schema and alter the search_path so that operator introspection probes, running as the cluster superuser, resolved those overloads before pg_catalog, a CWE-426 privilege-escalation chain (same class as CVE-2018-1058) that could lead to in-pod RCE via COPY ... FROM PROGRAM. The operator now pins search_path = pg_catalog, public, pg_temp on every pooled connection so it ships in the startup message and takes precedence over tenant-controlled defaults. (#10774, GHSA-x8c2-3p4r-v9r6) <!-- 1.29 1.28 1.25 -->

  • GHSA-7qwx-x8ff-3px9: authenticated operator-to-instance-manager calls: the instance manager's remote webserver relied on network isolation rather than authentication for its operator-only control endpoints, so any party able to reach the pod's status port could invoke them, disrupting backup orchestration and WAL archival and reading operational metadata. (The upgrade endpoint is SHA-256-pinned, so this did not permit arbitrary code execution.) The operator now generates an in-memory ECDSA P-256 client certificate at startup and reconciles its SHA-256 fingerprint into the cluster status; the instance manager rejects requests to sensitive endpoints that do not present a matching certificate. This hardening is not backported; earlier releases should continue to restrict the status port with a NetworkPolicy. (#10579, GHSA-7qwx-x8ff-3px9)

  • CVE-2026-55765 / GHSA-w3gf-xc94-wvmj: operator-side SCRAM-SHA-256 password encoding: the operator now SCRAM-SHA-256 encodes cleartext role passwords before issuing CREATE/ALTER ROLE ... PASSWORD, so the literal PostgreSQL parses (and that extensions such as pg_stat_statements or pgaudit may capture) is the SCRAM verifier rather than the cleartext secret. Pre-hashed (MD5 or SCRAM) values are forwarded unchanged, and the per-Secret annotation cnpg.io/passwordPassthrough: "enabled" opts out. (#10724, GHSA-w3gf-xc94-wvmj) <!-- 1.29 1.28 1.25 -->

Changes

  • Added support for Kubernetes 1.36. (#10900) <!-- 1.29 1.28 -->

  • Updated the default PostgreSQL version to 18.4. (#10719) <!-- 1.29 1.28 1.25 -->

  • Updated the Kubernetes versions used to test the operator on public cloud providers. ([#10720](https://github.com/cloudnativ

…(truncated)

Release date: Jun 29, 2026

Important changes

  • Updated the deprecation notice for native (in-tree) Barman Cloud support to reflect that it will now be removed in CloudNativePG 1.31.0, rather than 1.30.0. Users are still encouraged to migrate to the Barman Cloud Plugin. (#11083) <!-- 1.29 1.28 -->

  • The cluster reference is now immutable on the Database, Pooler, Publication, Subscription, and ScheduledBackup resources. Pointing one of these objects at a different cluster has no well-defined semantics and previously left the controllers in an inconsistent state; the update is now rejected at the API server via a CEL validation rule. (#10743) <!-- 1.29 1.28 1.25 -->

Enhancements

  • Enabled pg_upgrade in-place major upgrades to PostgreSQL 19 or later for clusters that use Image Volume extensions, building on the extension-path support added to pg_upgrade in PostgreSQL 19. During the upgrade Job, the source- and target-version extension images are mounted side by side, so the old server keeps its libraries and a failed upgrade reverts cleanly. (#10366) <!-- 1.29 -->

  • Added a label selector to the Cluster scale subresource (status.selector), making a Cluster a valid targetRef for the Vertical Pod Autoscaler (VPA) and Horizontal Pod Autoscaler (HPA), which can now map a Cluster to its instance pods. Contributed by @sebv004. (#8996) <!-- 1.29 1.28 1.25 -->

  • The operator now emits a Warning PrimaryStatusCheckFailed event on the Cluster when the primary pod is Ready from the kubelet perspective but the operator's /pg/status check fails and failover is deferred, giving users visibility into the deferral via kubectl describe cluster. (#10509) <!-- 1.29 1.28 1.25 -->

  • The operator now reloads a CNPG-i plugin automatically when its pods are rolled: it watches the EndpointSlices backing plugin Services and re-enqueues every cluster using the plugin once the new pods become Ready, so an upgraded plugin is picked up without waiting for the next resync. (#10836) <!-- 1.29 1.28 1.25 -->

Security and Supply Chain

  • CVE-2026-55769 / GHSA-x8c2-3p4r-v9r6: search_path pinning on operator-issued connections: a database owner could plant overloaded built-in operators in the public schema and alter the search_path so that operator introspection probes, running as the cluster superuser, resolved those overloads before pg_catalog, a CWE-426 privilege-escalation chain (same class as CVE-2018-1058) that could lead to in-pod RCE via COPY ... FROM PROGRAM. The operator now pins search_path = pg_catalog, public, pg_temp on every pooled connection so it ships in the startup message and takes precedence over tenant-controlled defaults. (#10774, GHSA-x8c2-3p4r-v9r6) <!-- 1.29 1.28 1.25 -->

  • CVE-2026-55765 / GHSA-w3gf-xc94-wvmj: operator-side SCRAM-SHA-256 password encoding: the operator now SCRAM-SHA-256 encodes cleartext role passwords before issuing CREATE/ALTER ROLE ... PASSWORD, so the literal PostgreSQL parses (and that extensions such as pg_stat_statements or pgaudit may capture) is the SCRAM verifier rather than the cleartext secret. Pre-hashed (MD5 or SCRAM) values are forwarded unchanged, and the per-Secret annotation cnpg.io/passwordPassthrough: "enabled" opts out. (#10724, GHSA-w3gf-xc94-wvmj) <!-- 1.29 1.28 1.25 -->

Changes

  • Added support for Kubernetes 1.36. (#10900) <!-- 1.29 1.28 -->

  • Updated the default PostgreSQL version to 18.4. (#10719) <!-- 1.29 1.28 1.25 -->

  • Updated the Kubernetes versions used to test the operator on public cloud providers. (#10720, <!-- 1.29 1.28 1.25 --> #10563, <!-- 1.29 1.28 1.25 --> #11033) <!-- 1.29 1.28 1.25 -->

Fixes

  • Fixed spec.postgresql.parameters accepting keys that are not valid PostgreSQL parameter names, which could inject arbitrary directives into postgresql.conf; key names are now validated by the webhook. (#11029) <!-- 1.29 1.28 1.25 -->

  • Fixed declarative Database, Publication, and Subscription objects reporting a stale primary-side status forever after their cluster was demoted to a replica; the controller now re-checks the replica condition and watches the Cluster so a demotion is detected promptly. (#10871) <!-- 1.29 1.28 1.25 -->

  • Fixed non-sequential pod names (for example -1, -3) caused by the instance serial counter being advanced before the corresponding Job and PVCs were created; the bump is now persisted only after those resources exist. (#10491) <!-- 1.29 1.28 1.25 -->

  • Fixed a switchover deadlock when a WAL-archiver plugin was enabled on an existing cluster: with primaryUpdateMethod: switchover the primary could not be rolled out because a clean demotion needs the archiver sidecar that is still missing. The operator now recreates the primary Pod in place so the sidecar is injected and archiving resumes. The check also covers plugins that inject the archiver as a native sidecar (an init container with restartPolicy: Always), such as the Barman Cloud plugin. (#11032, <!-- 1.29 1.28 1.25 --> #11059) <!-- 1.29 1.28 1.25 -->

  • Fixed a cluster staying in Setting up primary indefinitely when the instance-creation Job exhausted its backoff limit; the operator now detects the terminal Job failure and marks the cluster unrecoverable, naming the failed Job and pointing to its logs. (#11035) <!-- 1.29 1.28 1.25 -->

  • Fixed deletion of a Database, Publication, or Subscription getting stuck in Terminating on a replica cluster, where the replica gate ran before the finalizer reconciler and the finalizer was never released. On a replica the PostgreSQL object is left to the primary cluster. (#10853) <!-- 1.29 1.28 1.25 -->

  • Fixed a conflicting duplicate Database or Subscription with a delete reclaim policy dropping the PostgreSQL object owned by the surviving CR; the drop is now gated on a recorded reconciliation. (#10870) <!-- 1.29 1.28 1.25 -->

  • Fixed the postgres superuser being left locked out after superuser access was disabled and then re-enabled, because the cached secret version was not invalidated and the password was never re-applied. Diagnosed by @mhartmann-jaconi. (#10834) <!-- 1.29 1.28 1.25 -->

  • Fixed backups getting stuck in the started phase when the instance manager running them was restarted (for example by the in-place upgrade following an operator upgrade) before the backup reached running; the reconciliation is now rescheduled so the lost session is detected. (#10859) <!-- 1.29 1.28 -->

  • Fixed exec/attach streaming to negotiate WebSocket with a SPDY fallback, restoring compatibility both with Kubernetes versions that have removed SPDY and with platforms such as OpenShift that reject WebSocket exec upgrades. Contributed by @bartscheers. (#10876, #10933) <!-- 1.29 -->

  • Fixed resource leaks when concurrent Backup objects raced: backups now run in strict creation-time order, so an already-executing backup is never preempted by a newer one and its replication slot and PostgreSQL session are no longer orphaned on the primary. Contributed by @GabriFedi97. (#10747) <!-- 1.29 1.28 1.25 -->

  • Fixed role reconciliation clearing the password on a PostgreSQL role when the referenced Secret could not be fetched; the role is now left untouched until the Secret becomes available, and per-action errors are aggregated for better visibility. (#10053) <!-- 1.29 1.28 1.25 -->

  • Fixed a bootstrap failure where a metrics-exporter setup error (commonly a duplicate-key race with the controller) rolled back streaming_replica creation and wedged replica joins. The metrics-exporter step now runs in a separate transaction. Contributed by @BlaiseAntony. (#10749) <!-- 1.29 1.28 1.25 -->

  • Fixed a ScheduledBackup controller loop that occurred when a Backup was created but its status patch never landed; the controller now adopts an existing Backup for the next iteration instead of looping on `AlreadyExis

…(truncated)

Release date: Jun 29, 2026

:::warning This is the final release in the 1.28.x series. Users are strongly encouraged to upgrade to a newer minor version, as 1.28 is no longer supported. :::

Important changes

  • Updated the deprecation notice for native (in-tree) Barman Cloud support to reflect that it will now be removed in CloudNativePG 1.31.0, rather than 1.30.0. Users are still encouraged to migrate to the Barman Cloud Plugin. (#11083) <!-- 1.29 1.28 -->

  • The cluster reference is now immutable on the Database, Pooler, Publication, Subscription, and ScheduledBackup resources. Pointing one of these objects at a different cluster has no well-defined semantics and previously left the controllers in an inconsistent state; the update is now rejected at the API server via a CEL validation rule. (#10743) <!-- 1.29 1.28 1.25 -->

Enhancements

  • Added a label selector to the Cluster scale subresource (status.selector), making a Cluster a valid targetRef for the Vertical Pod Autoscaler (VPA) and Horizontal Pod Autoscaler (HPA), which can now map a Cluster to its instance pods. Contributed by @sebv004. (#8996) <!-- 1.29 1.28 1.25 -->

  • The operator now emits a Warning PrimaryStatusCheckFailed event on the Cluster when the primary pod is Ready from the kubelet perspective but the operator's /pg/status check fails and failover is deferred, giving users visibility into the deferral via kubectl describe cluster. (#10509) <!-- 1.29 1.28 1.25 -->

  • The operator now reloads a CNPG-i plugin automatically when its pods are rolled: it watches the EndpointSlices backing plugin Services and re-enqueues every cluster using the plugin once the new pods become Ready, so an upgraded plugin is picked up without waiting for the next resync. (#10836) <!-- 1.29 1.28 1.25 -->

Security and Supply Chain

  • CVE-2026-55769 / GHSA-x8c2-3p4r-v9r6: search_path pinning on operator-issued connections: a database owner could plant overloaded built-in operators in the public schema and alter the search_path so that operator introspection probes, running as the cluster superuser, resolved those overloads before pg_catalog, a CWE-426 privilege-escalation chain (same class as CVE-2018-1058) that could lead to in-pod RCE via COPY ... FROM PROGRAM. The operator now pins search_path = pg_catalog, public, pg_temp on every pooled connection so it ships in the startup message and takes precedence over tenant-controlled defaults. (#10774, GHSA-x8c2-3p4r-v9r6) <!-- 1.29 1.28 1.25 -->

  • CVE-2026-55765 / GHSA-w3gf-xc94-wvmj: operator-side SCRAM-SHA-256 password encoding: the operator now SCRAM-SHA-256 encodes cleartext role passwords before issuing CREATE/ALTER ROLE ... PASSWORD, so the literal PostgreSQL parses (and that extensions such as pg_stat_statements or pgaudit may capture) is the SCRAM verifier rather than the cleartext secret. Pre-hashed (MD5 or SCRAM) values are forwarded unchanged, and the per-Secret annotation cnpg.io/passwordPassthrough: "enabled" opts out. (#10724, GHSA-w3gf-xc94-wvmj) <!-- 1.29 1.28 1.25 -->

Changes

  • Added support for Kubernetes 1.35 and enabled unit tests on Kubernetes 1.36. (#10900) <!-- 1.29 1.28 -->

  • Updated the default PostgreSQL version to 18.4. (#10719) <!-- 1.29 1.28 1.25 -->

  • Updated the Kubernetes versions used to test the operator on public cloud providers. (#10720, <!-- 1.29 1.28 1.25 --> #10563, <!-- 1.29 1.28 1.25 --> #11033) <!-- 1.29 1.28 1.25 -->

Fixes

  • Fixed spec.postgresql.parameters accepting keys that are not valid PostgreSQL parameter names, which could inject arbitrary directives into postgresql.conf; key names are now validated by the webhook. (#11029) <!-- 1.29 1.28 1.25 -->

  • Fixed declarative Database, Publication, and Subscription objects reporting a stale primary-side status forever after their cluster was demoted to a replica; the controller now re-checks the replica condition and watches the Cluster so a demotion is detected promptly. (#10871) <!-- 1.29 1.28 1.25 -->

  • Fixed non-sequential pod names (for example -1, -3) caused by the instance serial counter being advanced before the corresponding Job and PVCs were created; the bump is now persisted only after those resources exist. (#10491) <!-- 1.29 1.28 1.25 -->

  • Fixed a switchover deadlock when a WAL-archiver plugin was enabled on an existing cluster: with primaryUpdateMethod: switchover the primary could not be rolled out because a clean demotion needs the archiver sidecar that is still missing. The operator now recreates the primary Pod in place so the sidecar is injected and archiving resumes. The check also covers plugins that inject the archiver as a native sidecar (an init container with restartPolicy: Always), such as the Barman Cloud plugin. (#11032, <!-- 1.29 1.28 1.25 --> #11059) <!-- 1.29 1.28 1.25 -->

  • Fixed a cluster staying in Setting up primary indefinitely when the instance-creation Job exhausted its backoff limit; the operator now detects the terminal Job failure and marks the cluster unrecoverable, naming the failed Job and pointing to its logs. (#11035) <!-- 1.29 1.28 1.25 -->

  • Fixed deletion of a Database, Publication, or Subscription getting stuck in Terminating on a replica cluster, where the replica gate ran before the finalizer reconciler and the finalizer was never released. On a replica the PostgreSQL object is left to the primary cluster. (#10853) <!-- 1.29 1.28 1.25 -->

  • Fixed a conflicting duplicate Database or Subscription with a delete reclaim policy dropping the PostgreSQL object owned by the surviving CR; the drop is now gated on a recorded reconciliation. (#10870) <!-- 1.29 1.28 1.25 -->

  • Fixed the postgres superuser being left locked out after superuser access was disabled and then re-enabled, because the cached secret version was not invalidated and the password was never re-applied. Diagnosed by @mhartmann-jaconi. (#10834) <!-- 1.29 1.28 1.25 -->

  • Fixed backups getting stuck in the started phase when the instance manager running them was restarted (for example by the in-place upgrade following an operator upgrade) before the backup reached running; the reconciliation is now rescheduled so the lost session is detected. (#10859) <!-- 1.29 1.28 -->

  • Fixed resource leaks when concurrent Backup objects raced: backups now run in strict creation-time order, so an already-executing backup is never preempted by a newer one and its replication slot and PostgreSQL session are no longer orphaned on the primary. Contributed by @GabriFedi97. (#10747) <!-- 1.29 1.28 1.25 -->

  • Fixed role reconciliation clearing the password on a PostgreSQL role when the referenced Secret could not be fetched; the role is now left untouched until the Secret becomes available, and per-action errors are aggregated for better visibility. (#10053) <!-- 1.29 1.28 1.25 -->

  • Fixed a bootstrap failure where a metrics-exporter setup error (commonly a duplicate-key race with the controller) rolled back streaming_replica creation and wedged replica joins. The metrics-exporter step now runs in a separate transaction. Contributed by @BlaiseAntony. (#10749) <!-- 1.29 1.28 1.25 -->

  • Fixed a ScheduledBackup controller loop that occurred when a Backup was created but its status patch never landed; the controller now adopts an existing Backup for the next iteration instead of looping on AlreadyExists. (#10612) <!-- 1.29 1.28 1.25 -->

  • Fixed a nil-pointer panic when reconciling a Pooler whose Cluster has been deleted. (#10667) <!-- 1.29 1.28 -->

  • Fixed bootstrap log handling so that all named log pipes (postgres, postgres.csv, and postgres.json) get consumers during WithActiveInstance, preventing regular files from being created in place of the named pipes. (#10043) <!-- 1.29 1.28 1.25 -->

  • Fixed generation of invalid IPv6 URLs by wrapping the address in

…(truncated)

Release date: May 8, 2026

Security and Supply Chain

  • CVE-2026-44477 / GHSA-423p-g724-fr39: metrics exporter privilege escalation: the metrics exporter no longer authenticates as the postgres superuser. It now uses a dedicated cnpg_metrics_exporter role with pg_monitor privileges only, closing a chain that let a low-privilege database user gain PostgreSQL superuser. (GHSA-423p-g724-fr39) <!-- 1.29 1.28 1.25 -->

    Upgrade impact: custom monitoring queries that read user-owned tables, or use target_databases: '*' against databases where PUBLIC CONNECT has been revoked, need explicit GRANT statements to cnpg_metrics_exporter. See "Custom query privileges and safety" and "Manually creating the metrics exporter role" in the monitoring documentation.

    For replica clusters, upgrade the source primary cluster before any replica clusters that consume from it. The cnpg_metrics_exporter role is created on the source primary and replicates downstream; a replica cluster upgraded first will scrape against a missing role until the source primary upgrades. The manual-recovery section linked above also covers replica clusters.

  • Schema-qualified catalog references in default monitoring queries: hardened the shipped monitoring configuration and documentation samples by qualifying every pg_catalog object explicitly. Unqualified references resolve through search_path, which a database user can manipulate to shadow built-in objects. (#10576) <!-- 1.29 1.28 1.25 -->

  • Discoverable SBOM and provenance attestations: SBOM and SLSA provenance attached to operator container images now follow the OCI 1.1 Referrers spec, so standard registry tooling and supply-chain scanners can discover them automatically. (#10601) <!-- 1.29 1.28 1.25 -->

  • CVE remediation in github.com/jackc/pgx/v5: bumped to v5.9.2 to pick up upstream fixes for CVE-2026-33816 (memory-safety in pgproto3) and GHSA-j88v-2chj-qfwx (SQL injection via simple-protocol dollar-quoted string handling). (#10437, #10499)

  • CVE remediation in the Go runtime: built with Go 1.26.3 to pick up upstream fixes in crypto/x509, crypto/tls, net/http, and net (CVE-2026-32280, CVE-2026-32281, CVE-2026-33810, CVE-2026-33814, CVE-2026-33811, CVE-2026-39825). (#10463, #10647) <!-- 1.29 1.28 1.25 -->

  • Build pipeline hardening: the Go 1.26.3 bump also addresses CVE-2026-42501 (cmd/go module-checksum validation), reducing supply-chain exposure during release builds. The affected code paths are not reachable from the running operator. (#10647) <!-- 1.29 1.28 1.25 -->

Changes

  • Switched TLS peer verification from VerifyPeerCertificate to VerifyConnection, which runs on every completed handshake (the former is skipped on resumed TLS 1.3 sessions). Session resumption is not enabled in CloudNativePG today, so this has no observable effect, but it future-proofs verification if session caching is introduced later. (#10478) <!-- 1.29 1.28 1.25 -->

Fixes

  • Fixed a failover window where the former primary kept its primary label. If it returned during failover (for example, after a transient network partition), the -rw service kept routing to it, replicas could reconnect, and committed writes were lost to pg_rewind. The old primary is now labeled unhealthy to isolate it from service traffic during failover. (#10409) <!-- 1.29 1.28 1.25 -->

  • Fixed failover not being triggered when the node hosting the primary becomes unreachable. The operator now reads the pod's Ready condition (flipped to False by the node controller when the kubelet stops reporting) instead of ContainersReady, which stays stale as True in that scenario. Combined with the spurious-failover guard (#10445), failover triggers only when Kubernetes itself marks the pod not Ready. (#10448) <!-- 1.29 1.28 1.25 -->

  • Fixed spurious failovers caused by transient failures on the primary's HTTP status endpoint. (#10445) <!-- 1.29 1.28 1.25 -->

  • Fixed escaping of backslashes and control characters in PostgreSQL configuration values. Previously, such characters in parameters like log_line_prefix could corrupt the configuration file or be silently stripped at runtime. (#10515) <!-- 1.29 1.28 1.25 -->

  • Fixed restore_command construction to shell-quote each argument. Values such as a destinationPath containing whitespace (for example, s3://my bucket/wal) were word-split by the POSIX shell and passed to the WAL restore tool as separate arguments. (#10518) <!-- 1.29 1.28 1.25 -->

  • Tightened recoveryTarget validation in the admission webhook: targetXID must now be a non-negative 32-bit integer, and targetName must be shorter than 64 bytes and free of ASCII control characters. Malformed values are rejected at admission instead of failing later during PostgreSQL recovery. (#10565) <!-- 1.29 1.28 1.25 -->

  • Fixed snapshot restores failing when leftover pgsql_tmp* directories were present in the data directory. (#10447) <!-- 1.29 1.28 1.25 -->

  • Fixed a deadlock occurring when PVC storage size and resource requests are changed simultaneously. (#10427) <!-- 1.29 1.28 1.25 -->

Release date: May 8, 2026

Security and Supply Chain

  • CVE-2026-44477 / GHSA-423p-g724-fr39: metrics exporter privilege escalation: the metrics exporter no longer authenticates as the postgres superuser. It now uses a dedicated cnpg_metrics_exporter role with pg_monitor privileges only, closing a chain that let a low-privilege database user gain PostgreSQL superuser. (GHSA-423p-g724-fr39) <!-- 1.29 1.28 1.25 -->

    Upgrade impact: custom monitoring queries that read user-owned tables, or use target_databases: '*' against databases where PUBLIC CONNECT has been revoked, need explicit GRANT statements to cnpg_metrics_exporter. See "Custom query privileges and safety" and "Manually creating the metrics exporter role" in the monitoring documentation.

    For replica clusters, upgrade the source primary cluster before any replica clusters that consume from it. The cnpg_metrics_exporter role is created on the source primary and replicates downstream; a replica cluster upgraded first will scrape against a missing role until the source primary upgrades. The manual-recovery section linked above also covers replica clusters.

  • Schema-qualified catalog references in default monitoring queries: hardened the shipped monitoring configuration and documentation samples by qualifying every pg_catalog object explicitly. Unqualified references resolve through search_path, which a database user can manipulate to shadow built-in objects. (#10576) <!-- 1.29 1.28 1.25 -->

  • Discoverable SBOM and provenance attestations: SBOM and SLSA provenance attached to operator container images now follow the OCI 1.1 Referrers spec, so standard registry tooling and supply-chain scanners can discover them automatically. (#10601) <!-- 1.29 1.28 1.25 -->

  • CVE remediation in github.com/jackc/pgx/v5: bumped to v5.9.2 to pick up upstream fixes for CVE-2026-33816 (memory-safety in pgproto3) and GHSA-j88v-2chj-qfwx (SQL injection via simple-protocol dollar-quoted string handling). (#10436, #10498)

  • CVE remediation in the Go runtime: built with Go 1.26.3 to pick up upstream fixes in crypto/x509, crypto/tls, net/http, and net (CVE-2026-32280, CVE-2026-32281, CVE-2026-33810, CVE-2026-33814, CVE-2026-33811, CVE-2026-39825). (#10462, #10647) <!-- 1.29 1.28 1.25 -->

  • Build pipeline hardening: the Go 1.26.3 bump also addresses CVE-2026-42501 (cmd/go module-checksum validation), reducing supply-chain exposure during release builds. The affected code paths are not reachable from the running operator. (#10647) <!-- 1.29 1.28 1.25 -->

Changes

  • Switched TLS peer verification from VerifyPeerCertificate to VerifyConnection, which runs on every completed handshake (the former is skipped on resumed TLS 1.3 sessions). Session resumption is not enabled in CloudNativePG today, so this has no observable effect, but it future-proofs verification if session caching is introduced later. (#10478) <!-- 1.29 1.28 1.25 -->

Fixes

  • Fixed a failover window where the former primary kept its primary label. If it returned during failover (for example, after a transient network partition), the -rw service kept routing to it, replicas could reconnect, and committed writes were lost to pg_rewind. The old primary is now labeled unhealthy to isolate it from service traffic during failover. (#10409) <!-- 1.29 1.28 1.25 -->

  • Fixed failover not being triggered when the node hosting the primary becomes unreachable. The operator now reads the pod's Ready condition (flipped to False by the node controller when the kubelet stops reporting) instead of ContainersReady, which stays stale as True in that scenario. Combined with the spurious-failover guard (#10445), failover triggers only when Kubernetes itself marks the pod not Ready. (#10448) <!-- 1.29 1.28 1.25 -->

  • Fixed spurious failovers caused by transient failures on the primary's HTTP status endpoint. (#10445) <!-- 1.29 1.28 1.25 -->

  • Fixed escaping of backslashes and control characters in PostgreSQL configuration values. Previously, such characters in parameters like log_line_prefix could corrupt the configuration file or be silently stripped at runtime. (#10515) <!-- 1.29 1.28 1.25 -->

  • Fixed restore_command construction to shell-quote each argument. Values such as a destinationPath containing whitespace (for example, s3://my bucket/wal) were word-split by the POSIX shell and passed to the WAL restore tool as separate arguments. (#10518) <!-- 1.29 1.28 1.25 -->

  • Tightened recoveryTarget validation in the admission webhook: targetXID must now be a non-negative 32-bit integer, and targetName must be shorter than 64 bytes and free of ASCII control characters. Malformed values are rejected at admission instead of failing later during PostgreSQL recovery. (#10565) <!-- 1.29 1.28 1.25 -->

  • Fixed snapshot restores failing when leftover pgsql_tmp* directories were present in the data directory. (#10447) <!-- 1.29 1.28 1.25 -->

  • Fixed a deadlock occurring when PVC storage size and resource requests are changed simultaneously. (#10427) <!-- 1.29 1.28 1.25 -->

Release date: Mar 31, 2026

Important changes

  • Updated the deprecation notice for native (in-tree) Barman Cloud support to reflect that it will now be removed in CloudNativePG 1.30.0, rather than 1.29.0. Users are still encouraged to migrate to the Barman Cloud Plugin. (#10167) <!-- 1.28 1.27 -->

Features

  • PostgreSQL extensions in image catalogs: extended the ImageCatalog functionality to support PostgreSQL extensions. This allows users to define and manage extension-specific images within a catalog, simplifying the deployment of customized PostgreSQL builds. (#9781)

  • Dynamic network access control via pod selectors: introduced the declarative definition of podSelectorRefs to manage pg_hba.conf rules dynamically. By using label selectors to identify client pods, the operator automatically resolves their ephemeral IP addresses and updates the PostgreSQL host-based authentication rules accordingly. This ensures that only authorized workloads in the same namespace can connect to the database, eliminating the need for manual IP management or static CIDR ranges. (#10148)

  • Shared ServiceAccount support: added an optional serviceAccountName field to both Cluster and Pooler specifications. This allows multiple resources to share a pre-existing ServiceAccount, facilitating one-time IAM configurations (such as AWS IRSA, GCP Workload Identity, or Azure Workload Identity) across all clusters and poolers. Contributed by @bozkayasalihx. (#9287)

Enhancements

  • Improved the Pooler CRD with support for granular configuration of TLS cipher suites and minimum/maximum TLS versions. This enables administrators to meet strict security compliance requirements for pooler-to-client and pooler-to-server connections. Contributed by @alex1989hu. (#9571) <!-- 1.28 1.27 1.25 -->

  • Improved the reliability of major upgrades by setting BackoffLimit=0 on the upgrade job, preventing unnecessary retries of a failed pg_upgrade. The operator now automatically deletes the failed job when a user reverts the container image, allowing the cluster to restart gracefully on the original version. (#10104, #10298) <!-- 1.28 1.27 -->

  • Improved the operator's observability by emitting native Kubernetes events during key phases of the reconciliation loop, providing visibility into the operator's decision-making process and the lifecycle of managed resources directly through kubectl get events. (#10040)

  • Extended support for the cnpg.io/reconciliationDisabled annotation on Backup resources. This allows administrators to temporarily freeze the operator's reconciliation logic for specific backup objects. Contributed by @GabriFedi97. (#10020)

  • Added a bin_path field to the postgresql.extensions stanza, as well as in ImageCatalog and ClusterImageCatalog resources. This allows extensions to specify directory paths for external binaries, which are automatically appended to the PATH environment variable of the Postgres process. (#10250)

  • Added an env field to the postgresql.extensions stanza, as well as in ImageCatalog and ClusterImageCatalog resources. This allows cluster administrators to define custom environment variables for the Postgres process. This field supports the ${image_root} placeholder to dynamically resolve to the extension's absolute mount path. (#10375)

  • Implemented a finalizer for plugins to ensure that resources managed by a plugin are gracefully cleaned up when the corresponding service is deleted. (#9560)

  • Improved role management by verifying the instance is the primary before each reconciliation cycle, avoiding unnecessary reconciliation attempts and spurious error messages on read-only replicas. (#9971) <!-- 1.28 1.27 1.25 -->

  • The operator now honors the primaryUpdateMethod when adding new PVCs to a cluster, ensuring that the rollout strategy (e.g., switchover vs. restart) is respected during storage expansion or additions. (#9720) <!-- 1.28 1.27 -->

  • Refined the alpha.cnpg.io/unrecoverable annotation logic to allow it to function even on pods that have not yet reached the Ready state, facilitating the recovery of stuck instances. (#9968) <!-- 1.28 -->

  • Introduced a "Terminal Error" phase for backups that encounter unrecoverable issues (such as invalid credentials or non-existent cloud buckets). This ensures the operator stops retrying doomed operations, preventing resource exhaustion and providing immediate, clear feedback in the status. (#9353)

  • Improved monitoring of long-running backups by introducing reconciliationStartedAt and reconciliationTerminatedAt fields to the Backup status. This change separates the operator's internal lifecycle from the actual backup tool's execution timing (startedAt/stoppedAt), allowing users to track when the operator begins processing a request. (#9351)

  • Added a Pending phase to the Backup status to explicitly indicate when a backup is queued and waiting for an available worker or instance availability. (#9364)

Security and Supply Chain

  • Security best practices integration: integrated the OpenSSF baseline scanner and added a SECURITY-INSIGHTS.yaml file to the repository to align with industry-standard security reporting. (#10054, <!-- 1.28 1.27 1.25 --> #10062) <!-- 1.28 1.27 1.25 -->

  • SLSA provenance and SBOMs: added SLSA (Supply-chain Levels for Software Artifacts) provenance to release binaries and container images. Additionally, enabled Software Bill of Materials (SBOM) generation within the GoReleaser pipeline for improved dependency transparency. (#10048, <!-- 1.28 1.27 1.25 --> #10074) <!-- 1.28 1.27 1.25 -->

  • Password leak prevention: fixed a potential security risk where PostgreSQL could leak role passwords in the logs during specific reconciliation phases. (#9950) <!-- 1.28 1.27 1.25 -->

Changes

  • Updated the default PostgreSQL version to 18.3 (image 18.3-system-trixie). (#10090) <!-- 1.28 1.27 1.25 -->

Fixes

  • Fixed a deadlock during operator upgrades affecting clusters using synchronous replication, where pods running the old and new operator versions computed different PostgreSQL configuration hashes, causing the uniformity check to block indefinitely and preventing both rolling updates and in-place upgrades from proceeding. (#10342) <!-- 1.28 -->

  • Fixed an issue where fencing annotations could not be processed when the WAL disk was full, because the disk space check blocked the instance manager from starting. The check is now performed later in the lifecycle loop, after fencing is evaluated. (#10302) <!-- 1.28 1.27 -->

  • Fixed an issue where replicas would get stuck in a Pending state if the VolumeSnapshot used for the initial bootstrap had been deleted. The operator now validates snapshot existence before use; if a snapshot is missing, it attempts to use the next available candidate or falls back to pg_basebackup. (#10192) <!-- 1.28 1.27 1.25 -->

  • Prevented the "supervised primary" rollout strategy from consuming all available rollout slots, which previously caused delays in scheduled updates. Contributed by @ermakov-oleg. (#9977) <!-- 1.28 1.27 1.25 -->

  • Fixed an issue where certain hot-standby parameter changes were not being correctly applied to replica clusters. (#9952) <!-- 1.28 1.27 1.25 -->

  • Fixed a bug in the CNPG-I reconciler hook that could lead to skipping subsequent plugins when a "continue" result was returned. Contributed by @sharifmshaker. (#9978) <!-- 1.28 1.27 -->

  • Fixed a deadlock scenario that occurred when attempting to resize a filesystem on a PVC that was not currently attached to a Pod. Contributed by @jmealo. (#9981) <!-- 1.28 1.27 -->

  • Fixed webhook validation of bootstrap recovery sources to accept external clusters configured with ConnectionParameters (for pg_basebackup-based recovery). Previously, these were incorrectly rejected unless a Barman object store or CNPG-i plugin was also configu

…(truncated)

Release date: Mar 31, 2026

Important changes

  • Updated the deprecation notice for native (in-tree) Barman Cloud support to reflect that it will now be removed in CloudNativePG 1.30.0, rather than 1.29.0. Users are still encouraged to migrate to the Barman Cloud Plugin. (#10167) <!-- 1.28 1.27 -->

Enhancements

  • Improved the Pooler CRD with support for granular configuration of TLS cipher suites and minimum/maximum TLS versions. This enables administrators to meet strict security compliance requirements for pooler-to-client and pooler-to-server connections. Contributed by @alex1989hu. (#9571) <!-- 1.28 1.27 1.25 -->

  • Improved the reliability of major upgrades by setting BackoffLimit=0 on the upgrade job, preventing unnecessary retries of a failed pg_upgrade. The operator now automatically deletes the failed job when a user reverts the container image, allowing the cluster to restart gracefully on the original version. (#10104, #10298) <!-- 1.28 1.27 -->

  • Improved role management by verifying the instance is the primary before each reconciliation cycle, avoiding unnecessary reconciliation attempts and spurious error messages on read-only replicas. (#9971) <!-- 1.28 1.27 1.25 -->

  • Extended the CRD schemas for Cluster, ImageCatalog, and ClusterImageCatalog to accept the extensions, bin_path, and env fields introduced in 1.29. The operator ignores these fields on older versions, but accepting them in the schema allows users to share a single manifest across clusters running different CNPG versions. (#10131, #10387) <!-- 1.28 1.27 -->

  • The operator now honors the primaryUpdateMethod when adding new PVCs to a cluster, ensuring that the rollout strategy (e.g., switchover vs. restart) is respected during storage expansion or additions. (#9720) <!-- 1.28 1.27 -->

  • Refined the alpha.cnpg.io/unrecoverable annotation logic to allow it to function even on pods that have not yet reached the Ready state, facilitating the recovery of stuck instances. (#9968) <!-- 1.28 -->

Security and Supply Chain

  • Security best practices integration: integrated the OpenSSF baseline scanner and added a SECURITY-INSIGHTS.yaml file to the repository to align with industry-standard security reporting. (#10054, <!-- 1.28 1.27 1.25 --> #10062) <!-- 1.28 1.27 1.25 -->

  • SLSA provenance and SBOMs: added SLSA (Supply-chain Levels for Software Artifacts) provenance to release binaries and container images. Additionally, enabled Software Bill of Materials (SBOM) generation within the GoReleaser pipeline for improved dependency transparency. (#10048, <!-- 1.28 1.27 1.25 --> #10074) <!-- 1.28 1.27 1.25 -->

  • Password leak prevention: fixed a potential security risk where PostgreSQL could leak role passwords in the logs during specific reconciliation phases. (#9950) <!-- 1.28 1.27 1.25 -->

Changes

  • Updated the default PostgreSQL version to 18.3 (image 18.3-system-trixie). (#10090) <!-- 1.28 1.27 1.25 -->

Fixes

  • Fixed a deadlock during operator upgrades affecting clusters using synchronous replication, where pods running the old and new operator versions computed different PostgreSQL configuration hashes, causing the uniformity check to block indefinitely and preventing both rolling updates and in-place upgrades from proceeding. (#10342) <!-- 1.28 -->

  • Fixed an issue where fencing annotations could not be processed when the WAL disk was full, because the disk space check blocked the instance manager from starting. The check is now performed later in the lifecycle loop, after fencing is evaluated. (#10302) <!-- 1.28 1.27 -->

  • Fixed an issue where replicas would get stuck in a Pending state if the VolumeSnapshot used for the initial bootstrap had been deleted. The operator now validates snapshot existence before use; if a snapshot is missing, it attempts to use the next available candidate or falls back to pg_basebackup. (#10192) <!-- 1.28 1.27 1.25 -->

  • Prevented the "supervised primary" rollout strategy from consuming all available rollout slots, which previously caused delays in scheduled updates. Contributed by @ermakov-oleg. (#9977) <!-- 1.28 1.27 1.25 -->

  • Fixed an issue where certain hot-standby parameter changes were not being correctly applied to replica clusters. (#9952) <!-- 1.28 1.27 1.25 -->

  • Fixed a bug in the CNPG-I reconciler hook that could lead to skipping subsequent plugins when a "continue" result was returned. Contributed by @sharifmshaker. (#9978) <!-- 1.28 1.27 -->

  • Fixed a deadlock scenario that occurred when attempting to resize a filesystem on a PVC that was not currently attached to a Pod. Contributed by @jmealo. (#9981) <!-- 1.28 1.27 -->

  • Fixed webhook validation of bootstrap recovery sources to accept external clusters configured with ConnectionParameters (for pg_basebackup-based recovery). Previously, these were incorrectly rejected unless a Barman object store or CNPG-i plugin was also configured. (#10268) <!-- 1.28 1.27 1.25 -->

  • Volume names for extensions and tablespaces are now prefixed to avoid naming collisions with standard cluster volumes. (#9973) <!-- 1.28 1.27 -->

  • When hibernating a non-healthy cluster, the operator now reports a WaitingForHealthy condition, making the deferred hibernation state visible through cnpg status. (#10193) <!-- 1.28 1.27 1.25 -->

  • Fixed fencing to work correctly even when the target pod does not exist. Fencing operates on a cluster-level annotation and should not depend on pod existence; instance name validation is now performed only in the cnpg fencing on command. (#10035) <!-- 1.28 1.27 1.25 -->

  • Fixed the cluster and pooler service reconcilers to correctly handle changes to all spec fields when using the patch update strategy. The reconciler now uses RFC 7386 JSON Merge Patching, preventing cloud-provider-set fields (such as loadBalancerClass) from being inadvertently removed. (#10190, #10311) <!-- 1.28 1.27 1.25 -->

  • Fixed a race condition in the deprecated in-tree Barman Cloud backup implementation affecting parallel WAL restore, where prefetched files could be read while still being downloaded, causing PostgreSQL recovery to fail with "invalid checkpoint record" errors. (#10285) <!-- 1.28 1.27 1.25 -->

  • Fixed the timeline history file validation to also apply to plugin-based WAL restore. Previously, the protection introduced in #9650 only covered in-tree restores, allowing plugins to bypass the check and download future timeline history files, causing timeline mismatch errors on replicas. (#9849) <!-- 1.28 1.27 1.25 -->

  • cnpg plugin:

    • The cnpg plugin now correctly propagates ImagePullSecrets to the pgbench Job pod template. (#10174) <!-- 1.28 1.27 1.25 -->

Release date: Mar 31, 2026

:::warning This is the final release in the 1.27.x series. Users are strongly encouraged to upgrade to a newer minor version, as 1.27 is no longer supported. :::

Important changes

  • Updated the deprecation notice for native (in-tree) Barman Cloud support to reflect that it will now be removed in CloudNativePG 1.30.0, rather than 1.29.0. Users are still encouraged to migrate to the Barman Cloud Plugin. (#10167) <!-- 1.28 1.27 -->

Enhancements

  • Improved the Pooler CRD with support for granular configuration of TLS cipher suites and minimum/maximum TLS versions. This enables administrators to meet strict security compliance requirements for pooler-to-client and pooler-to-server connections. Contributed by @alex1989hu. (#9571) <!-- 1.28 1.27 1.25 -->

  • Improved the reliability of major upgrades by setting BackoffLimit=0 on the upgrade job, preventing unnecessary retries of a failed pg_upgrade. The operator now automatically deletes the failed job when a user reverts the container image, allowing the cluster to restart gracefully on the original version. (#10104, #10298) <!-- 1.28 1.27 -->

  • Improved role management by verifying the instance is the primary before each reconciliation cycle, avoiding unnecessary reconciliation attempts and spurious error messages on read-only replicas. (#9971) <!-- 1.28 1.27 1.25 -->

  • Extended the CRD schemas for Cluster, ImageCatalog, and ClusterImageCatalog to accept the extensions, bin_path, and env fields introduced in 1.29. The operator ignores these fields on older versions, but accepting them in the schema allows users to share a single manifest across clusters running different CNPG versions. (#10131, #10387) <!-- 1.28 1.27 -->

  • The operator now honors the primaryUpdateMethod when adding new PVCs to a cluster, ensuring that the rollout strategy (e.g., switchover vs. restart) is respected during storage expansion or additions. (#9720) <!-- 1.28 1.27 -->

Security and Supply Chain

  • Security best practices integration: integrated the OpenSSF baseline scanner and added a SECURITY-INSIGHTS.yaml file to the repository to align with industry-standard security reporting. (#10054, <!-- 1.28 1.27 1.25 --> #10062) <!-- 1.28 1.27 1.25 -->

  • SLSA provenance and SBOMs: added SLSA (Supply-chain Levels for Software Artifacts) provenance to release binaries and container images. Additionally, enabled Software Bill of Materials (SBOM) generation within the GoReleaser pipeline for improved dependency transparency. (#10048, <!-- 1.28 1.27 1.25 --> #10074) <!-- 1.28 1.27 1.25 -->

  • Password leak prevention: fixed a potential security risk where PostgreSQL could leak role passwords in the logs during specific reconciliation phases. (#9950) <!-- 1.28 1.27 1.25 -->

Changes

  • Updated the default PostgreSQL version to 18.3 (image 18.3-system-trixie). (#10090) <!-- 1.28 1.27 1.25 -->

Fixes

  • Fixed an issue where fencing annotations could not be processed when the WAL disk was full, because the disk space check blocked the instance manager from starting. The check is now performed later in the lifecycle loop, after fencing is evaluated. (#10302) <!-- 1.28 1.27 -->

  • Fixed an issue where replicas would get stuck in a Pending state if the VolumeSnapshot used for the initial bootstrap had been deleted. The operator now validates snapshot existence before use; if a snapshot is missing, it attempts to use the next available candidate or falls back to pg_basebackup. (#10192) <!-- 1.28 1.27 1.25 -->

  • Prevented the "supervised primary" rollout strategy from consuming all available rollout slots, which previously caused delays in scheduled updates. Contributed by @ermakov-oleg. (#9977) <!-- 1.28 1.27 1.25 -->

  • Fixed an issue where certain hot-standby parameter changes were not being correctly applied to replica clusters. (#9952) <!-- 1.28 1.27 1.25 -->

  • Fixed a bug in the CNPG-I reconciler hook that could lead to skipping subsequent plugins when a "continue" result was returned. Contributed by @sharifmshaker. (#9978) <!-- 1.28 1.27 -->

  • Fixed a deadlock scenario that occurred when attempting to resize a filesystem on a PVC that was not currently attached to a Pod. Contributed by @jmealo. (#9981) <!-- 1.28 1.27 -->

  • Fixed webhook validation of bootstrap recovery sources to accept external clusters configured with ConnectionParameters (for pg_basebackup-based recovery). Previously, these were incorrectly rejected unless a Barman object store or CNPG-i plugin was also configured. (#10268) <!-- 1.28 1.27 1.25 -->

  • Volume names for extensions and tablespaces are now prefixed to avoid naming collisions with standard cluster volumes. (#9973) <!-- 1.28 1.27 -->

  • When hibernating a non-healthy cluster, the operator now reports a WaitingForHealthy condition, making the deferred hibernation state visible through cnpg status. (#10193) <!-- 1.28 1.27 1.25 -->

  • Fixed fencing to work correctly even when the target pod does not exist. Fencing operates on a cluster-level annotation and should not depend on pod existence; instance name validation is now performed only in the cnpg fencing on command. (#10035) <!-- 1.28 1.27 1.25 -->

  • Fixed the cluster and pooler service reconcilers to correctly handle changes to all spec fields when using the patch update strategy. The reconciler now uses RFC 7386 JSON Merge Patching, preventing cloud-provider-set fields (such as loadBalancerClass) from being inadvertently removed. (#10190, #10311) <!-- 1.28 1.27 1.25 -->

  • Fixed a race condition in the deprecated in-tree Barman Cloud backup implementation affecting parallel WAL restore, where prefetched files could be read while still being downloaded, causing PostgreSQL recovery to fail with "invalid checkpoint record" errors. (#10285) <!-- 1.28 1.27 1.25 -->

  • Fixed the timeline history file validation to also apply to plugin-based WAL restore. Previously, the protection introduced in #9650 only covered in-tree restores, allowing plugins to bypass the check and download future timeline history files, causing timeline mismatch errors on replicas. (#9849) <!-- 1.28 1.27 1.25 -->

  • cnpg plugin:

    • The cnpg plugin now correctly propagates ImagePullSecrets to the pgbench Job pod template. (#10174) <!-- 1.28 1.27 1.25 -->