@@ -11,6 +11,257 @@ For a complete list of changes, please refer to the
1111[ commits] ( https://github.com/cloudnative-pg/cloudnative-pg/commits/release-1.28 )
1212on the release branch in GitHub.
1313
14+ ## Version 1.28.4
15+
16+ ** Release date:** Jun 29, 2026
17+
18+ ::: warning
19+ This is the final release in the 1.28.x series.
20+ Users are strongly encouraged to upgrade to a newer minor version, as 1.28
21+ is no longer supported.
22+ :::
23+
24+ ### Important changes
25+
26+ - The ` cluster ` reference is now immutable on the ` Database ` , ` Pooler ` ,
27+ ` Publication ` , ` Subscription ` , and ` ScheduledBackup ` resources. Pointing
28+ one of these objects at a different cluster has no well-defined semantics and
29+ previously left the controllers in an inconsistent state; the update is now
30+ rejected at the API server via a CEL validation rule.
31+ ([ #10743 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10743 ) ) <!-- 1.29 1.28 1.25 -->
32+
33+ ### Enhancements
34+
35+ - Added a label selector to the ` Cluster ` scale subresource
36+ (` status.selector ` ), making a ` Cluster ` a valid ` targetRef ` for the Vertical
37+ Pod Autoscaler (VPA) and Horizontal Pod Autoscaler (HPA), which can now map a
38+ ` Cluster ` to its instance pods.
39+ Contributed by @sebv004 .
40+ ([ #8996 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/8996 ) ) <!-- 1.29 1.28 1.25 -->
41+
42+ - The operator now emits a ` Warning ` ` PrimaryStatusCheckFailed ` event on the
43+ ` Cluster ` when the primary pod is ` Ready ` from the kubelet perspective but
44+ the operator's ` /pg/status ` check fails and failover is deferred, giving
45+ users visibility into the deferral via ` kubectl describe cluster ` .
46+ ([ #10509 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10509 ) ) <!-- 1.29 1.28 1.25 -->
47+
48+ - The operator now reloads a CNPG-i plugin automatically when its pods are
49+ rolled: it watches the ` EndpointSlices ` backing plugin ` Services ` and
50+ re-enqueues every cluster using the plugin once the new pods become ` Ready ` ,
51+ so an upgraded plugin is picked up without waiting for the next resync.
52+ ([ #10836 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10836 ) ) <!-- 1.29 1.28 1.25 -->
53+
54+ ### Security and Supply Chain
55+
56+ - ** ` search_path ` pinning on operator-issued connections** : a database owner
57+ could plant overloaded built-in operators in the ` public ` schema and alter the
58+ ` search_path ` so that operator introspection probes, running as the cluster
59+ superuser, resolved those overloads before ` pg_catalog ` , a ` CWE-426 `
60+ privilege-escalation chain (same class as ` CVE-2018-1058 ` ) that could lead to
61+ in-pod RCE via ` COPY ... FROM PROGRAM ` . The operator now pins
62+ ` search_path = pg_catalog, public, pg_temp ` on every pooled connection so it
63+ ships in the startup message and takes precedence over tenant-controlled
64+ defaults.
65+ ([ #10774 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10774 ) ) <!-- 1.29 1.28 1.25 -->
66+
67+ - ** Operator-side SCRAM-SHA-256 password encoding** : the operator now
68+ SCRAM-SHA-256 encodes cleartext role passwords before issuing
69+ ` CREATE ` /` ALTER ROLE ... PASSWORD ` , so the literal PostgreSQL parses (and that
70+ extensions such as ` pg_stat_statements ` or ` pgaudit ` may capture) is the SCRAM
71+ verifier rather than the cleartext secret. Pre-hashed (MD5 or SCRAM) values
72+ are forwarded unchanged, and the per-Secret annotation
73+ ` cnpg.io/passwordPassthrough: "enabled" ` opts out.
74+ ([ #10724 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10724 ) ) <!-- 1.29 1.28 1.25 -->
75+
76+ ### Changes
77+
78+ - Added support for Kubernetes 1.35 and enabled unit tests on Kubernetes 1.36.
79+ ([ #10900 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10900 ) ) <!-- 1.29 1.28 -->
80+
81+ - Updated the default PostgreSQL version to 18.4.
82+ ([ #10719 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10719 ) ) <!-- 1.29 1.28 1.25 -->
83+
84+ - Updated the Kubernetes versions used to test the operator on public cloud
85+ providers.
86+ ([ #10720 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10720 ) , <!-- 1.29 1.28 1.25 -->
87+ [ #10563 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10563 ) ) <!-- 1.29 1.28 1.25 -->
88+
89+ ### Fixes
90+
91+ - Fixed ` spec.postgresql.parameters ` accepting keys that are not valid
92+ PostgreSQL parameter names, which could inject arbitrary directives into
93+ ` postgresql.conf ` ; key names are now validated by the webhook.
94+ ([ #11029 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/11029 ) ) <!-- 1.29 1.28 1.25 -->
95+
96+ - Fixed declarative ` Database ` , ` Publication ` , and ` Subscription ` objects
97+ reporting a stale primary-side status forever after their cluster was demoted
98+ to a replica; the controller now re-checks the replica condition and watches
99+ the ` Cluster ` so a demotion is detected promptly.
100+ ([ #10871 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10871 ) ) <!-- 1.29 1.28 1.25 -->
101+
102+ - Fixed non-sequential pod names (for example ` -1 ` , ` -3 ` ) caused by the instance
103+ serial counter being advanced before the corresponding ` Job ` and PVCs were
104+ created; the bump is now persisted only after those resources exist.
105+ ([ #10491 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10491 ) ) <!-- 1.29 1.28 1.25 -->
106+
107+ - Fixed a switchover deadlock when a WAL-archiver plugin was enabled on an
108+ existing cluster: with ` primaryUpdateMethod: switchover ` the primary could
109+ not be rolled out because a clean demotion needs the archiver sidecar that is
110+ still missing. The operator now recreates the primary Pod in place so the
111+ sidecar is injected and archiving resumes.
112+ ([ #11032 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/11032 ) ) <!-- 1.29 1.28 1.25 -->
113+
114+ - Fixed a cluster staying in ` Setting up primary ` indefinitely when the
115+ instance-creation Job exhausted its backoff limit; the operator now detects
116+ the terminal Job failure and marks the cluster unrecoverable, naming the
117+ failed Job and pointing to its logs.
118+ ([ #11035 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/11035 ) ) <!-- 1.29 1.28 1.25 -->
119+
120+ - Fixed deletion of a ` Database ` , ` Publication ` , or ` Subscription ` getting stuck
121+ in ` Terminating ` on a replica cluster, where the replica gate ran before the
122+ finalizer reconciler and the finalizer was never released. On a replica the
123+ PostgreSQL object is left to the primary cluster.
124+ ([ #10853 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10853 ) ) <!-- 1.29 1.28 1.25 -->
125+
126+ - Fixed a conflicting duplicate ` Database ` or ` Subscription ` with a ` delete `
127+ reclaim policy dropping the PostgreSQL object owned by the surviving CR; the
128+ drop is now gated on a recorded reconciliation.
129+ ([ #10870 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10870 ) ) <!-- 1.29 1.28 1.25 -->
130+
131+ - Fixed the ` postgres ` superuser being left locked out after superuser access
132+ was disabled and then re-enabled, because the cached secret version was not
133+ invalidated and the password was never re-applied.
134+ Diagnosed by @mhartmann-jaconi .
135+ ([ #10834 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10834 ) ) <!-- 1.29 1.28 1.25 -->
136+
137+ - Fixed backups getting stuck in the ` started ` phase when the instance manager
138+ running them was restarted (for example by the in-place upgrade following an
139+ operator upgrade) before the backup reached ` running ` ; the reconciliation is
140+ now rescheduled so the lost session is detected.
141+ ([ #10859 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10859 ) ) <!-- 1.29 1.28 -->
142+
143+ - Fixed resource leaks when concurrent ` Backup ` objects raced: backups now run
144+ in strict creation-time order, so an already-executing backup is never
145+ preempted by a newer one and its replication slot and PostgreSQL session are
146+ no longer orphaned on the primary.
147+ Contributed by @GabriFedi97 .
148+ ([ #10747 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10747 ) ) <!-- 1.29 1.28 1.25 -->
149+
150+ - Fixed role reconciliation clearing the password on a PostgreSQL role when the
151+ referenced Secret could not be fetched; the role is now left untouched until
152+ the Secret becomes available, and per-action errors are aggregated for better
153+ visibility.
154+ ([ #10053 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10053 ) ) <!-- 1.29 1.28 1.25 -->
155+
156+ - Fixed a bootstrap failure where a metrics-exporter setup error (commonly a
157+ duplicate-key race with the controller) rolled back ` streaming_replica `
158+ creation and wedged replica joins. The metrics-exporter step now runs in a
159+ separate transaction.
160+ Contributed by @BlaiseAntony .
161+ ([ #10749 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10749 ) ) <!-- 1.29 1.28 1.25 -->
162+
163+ - Fixed a ` ScheduledBackup ` controller loop that occurred when a ` Backup ` was
164+ created but its status patch never landed; the controller now adopts an
165+ existing ` Backup ` for the next iteration instead of looping on
166+ ` AlreadyExists ` .
167+ ([ #10612 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10612 ) ) <!-- 1.29 1.28 1.25 -->
168+
169+ - Fixed a nil-pointer panic when reconciling a ` Pooler ` whose ` Cluster ` has
170+ been deleted.
171+ ([ #10667 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10667 ) ) <!-- 1.29 1.28 -->
172+
173+ - Fixed bootstrap log handling so that all named log pipes (` postgres ` ,
174+ ` postgres.csv ` , and ` postgres.json ` ) get consumers during
175+ ` WithActiveInstance ` , preventing regular files from being created in place of
176+ the named pipes.
177+ ([ #10043 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10043 ) ) <!-- 1.29 1.28 1.25 -->
178+
179+ - Fixed generation of invalid IPv6 URLs by wrapping the address in square
180+ brackets.
181+ Contributed by @Infinoid .
182+ ([ #10682 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10682 ) ) <!-- 1.29 1.28 1.25 -->
183+
184+ - Fixed an external cluster plugin still being treated as active when its
185+ configuration set ` enabled: false ` .
186+ ([ #10932 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10932 ) ) <!-- 1.29 1.28 1.25 -->
187+
188+ - Fixed a race during bootstrap recovery from an object store where the restore
189+ job could read a stale ` Cluster ` (primary not yet recorded and timeline still
190+ unset) and have its ` .history ` files rejected by the split-brain guard. When
191+ this happened, recovery stopped at the base backup's timeline and silently
192+ dropped transactions committed on later timelines. History files are now
193+ allowed while the cluster timeline is unset.
194+ Contributed by @dennispidun .
195+ ([ #10818 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10818 ) ) <!-- 1.29 1.28 1.25 -->
196+
197+ - Fixed a cache race during cluster creation when the server and client CA
198+ resolve to the same Secret (the default): a stale informer cache triggered a
199+ redundant ` Create ` that failed with ` AlreadyExists ` and could leave the
200+ cluster stuck in ` Unable to create required cluster objects ` . The operator
201+ now reuses the already-fetched CA Secret when the names match.
202+ ([ #10989 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10989 ) ) <!-- 1.29 1.28 1.25 -->
203+
204+ - Fixed the ` pg_basebackup ` bootstrap path overwriting or failing on a
205+ pre-existing ` PGDATA ` (for example after a replica Pod restart) by enforcing
206+ the same pre-flight directory check already applied by the other bootstrap
207+ methods; this also protects statically provisioned PVCs from being silently
208+ overwritten.
209+ ([ #11006 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/11006 ) ) <!-- 1.29 1.28 1.25 -->
210+
211+ - Fixed the ` Cluster ` phase flapping between ` Healthy ` and a plugin-failure
212+ phase when a post-reconcile plugin hook returned an error; the ` Healthy `
213+ phase is now registered as the last step of a successful reconciliation, so a
214+ loop that ends in a plugin error never reports ` Healthy ` .
215+ Contributed by @GabriFedi97 .
216+ ([ #10421 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10421 ) ) <!-- 1.29 1.28 1.25 -->
217+
218+ - Fixed stale certificate data and partial reads after an external server's
219+ Secret was rotated (for example a CA bundle shrinking from two certificates
220+ to one): the file is now written atomically, so libpq always reads either the
221+ old or the new value, never a mix.
222+ Contributed by @Anand-240 .
223+ ([ #10975 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10975 ) ) <!-- 1.29 1.28 1.25 -->
224+
225+ - Fixed plugin connectivity to use the plugin ` Service ` FQDN instead of its
226+ short name, avoiding failures when a cluster-level proxy is automatically
227+ injected into pods.
228+ Contributed by @kdautrey .
229+ ([ #10921 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10921 ) ) <!-- 1.29 1.28 1.25 -->
230+
231+ - Fixed excessive operator log noise from the per-request ` Cluster `
232+ create/update validation webhook messages, now logged at ` debug `
233+ instead of ` info ` .
234+ ([ #10984 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10984 ) ) <!-- 1.29 1.28 1.25 -->
235+
236+ - Fixed a first-primary bootstrap deadlock where a status-patch conflict after
237+ the data PVC was created but before the initialization Job was started left
238+ the orphan Pending PVC counted as an instance, blocking the bootstrap gate;
239+ the PVC-state reconciler now recreates the bootstrap Job reusing the assigned
240+ serial.
241+ ([ #11039 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/11039 ) ) <!-- 1.29 1.28 1.25 -->
242+
243+ - Fixed external cluster names and secret selector references being joined into
244+ filesystem paths without validation, letting a ` .. ` component or path
245+ separator escape the external secrets directory when the instance manager
246+ dumps connection material; these values are now rejected at the validating
247+ webhook and re-checked at the write site.
248+ Reported by @r0binak .
249+ ([ #11045 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/11045 ) ) <!-- 1.29 1.28 1.25 -->
250+
251+ - ` cnpg ` plugin:
252+
253+ - Fixed ` kubectl cnpg psql ` on Windows, where execution relied on a
254+ Unix-only system call and failed with "not supported by windows"; Windows
255+ now launches ` kubectl exec ` as a child process.
256+ Contributed by @Utkarsh-sharma47 .
257+ ([ #10972 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10972 ) ) <!-- 1.29 1.28 1.25 -->
258+
259+ - Fixed an unbounded memory leak in ` kubectl cnpg logs -f ` on busy
260+ clusters, where a per-log-group timer was never released; timers are now
261+ reused across iterations.
262+ Contributed by @Anand-240 .
263+ ([ #10976 ] ( https://github.com/cloudnative-pg/cloudnative-pg/pull/10976 ) ) <!-- 1.29 1.28 1.25 -->
264+
14265## Version 1.28.3
15266
16267** Release date:** May 8, 2026
0 commit comments