PostgreSQL 14 gets its last release on 12 November 2026. After that, the PostgreSQL project stops fixing it, and 2026 shows what that means: this year's three quarterly releases fixed 36 CVEs that affect 14, 22 of them rated 8.0 or higher. The next bug found in code that 14 shares with newer versions will be fixed in 15 to 18 and left open in 14.
This post is for teams running PostgreSQL 14 on their own servers, in containers or on a managed service. It covers the dates that apply to you, what 2026's security releases fixed, two upgrade changes that affect security settings, and a script that finds every place a repository pins a PostgreSQL version.
The short answer
PostgreSQL 14's final minor release is scheduled for 12 November 2026, the project's next quarterly release date. In 2026, PostgreSQL 14 received fixes for 36 CVEs: 4 in 14.21 (12 February), 8 in 14.23 (14 May) and 24 in 14.24 (13 August), 22 of them rated CVSS 8.0 or higher. After 12 November, new vulnerabilities in 14 stay unfixed upstream. Amazon RDS keeps PostgreSQL 14 in standard support until 28 February 2027 and offers paid Extended Support after that, but minor versions 14.18 and 14.19 leave RDS standard support on 31 October 2026. Plan a major upgrade to PostgreSQL 18, supported until November 2030, and review two defaults the jump changes: CREATE on the public schema and MD5 passwords.
The dates that apply to you
| What | Date | Source |
|---|---|---|
| PostgreSQL 14 final release (community end of life) | 12 November 2026 | postgresql.org versioning policy and roadmap |
| Last scheduled minor releases for 14 | 13 August 2026 (14.24) and 12 November 2026 | postgresql.org release notes and roadmap |
| Amazon RDS: 14.18 and 14.19 leave standard support | 31 October 2026 | RDS for PostgreSQL release calendar |
| Amazon RDS: PostgreSQL 14 end of standard support | 28 February 2027 | RDS release calendar |
| Amazon RDS: Extended Support for 14 (paid) | 1 March 2027 to 28 February 2030 | RDS release calendar |
| PostgreSQL 15 end of life | 11 November 2027 | postgresql.org versioning policy |
| PostgreSQL 18 end of life | 14 November 2030 | postgresql.org versioning policy |
Other managed services publish their own calendars. Check yours, since a provider's extended support usually means the provider backports fixes, not the PostgreSQL project.
Upgrading to 15 buys one year. Upgrading to 18 buys four, and pg_upgrade supports going from 14 straight to 18.
What 2026's security releases fixed in 14
We read PostgreSQL's security page and counted the CVEs it lists as affecting version 14, grouped by the 14.x release that fixed them:
| Release | Date | CVEs affecting 14 | CVSS 8.0 or higher | Component |
|---|---|---|---|---|
| 14.21 | 12 February 2026 | 4 | 3 | core server 2, contrib 2 |
| 14.23 | 14 May 2026 | 8 | 4 | core server 5, client 2, contrib 1 |
| 14.24 | 13 August 2026 | 24 | 15 | core server 15, client 4, contrib 5 |
Most of the high scores need a logged-in database user (PR:L in the vectors), so the realistic threat is an application account, a reporting user or a compromised service turning into code execution as the database server. A few need no login at all, such as CVE-2026-6479, a denial of service during SSL or GSS connection setup fixed in 14.23. The client-side ones matter too: in 14.24, CVE-2026-19385 is a heap buffer overflow in pg_dump, and CVE-2026-18408 lets the superuser of the server you dumped from run code in the psql that restores the dump.
Not every new bug reaches 14. Eight 2026 CVEs on the page affect only newer versions, because they're in features 14 doesn't have. But most of 2026's bugs were in code all five supported versions share, and that's the code that stops getting fixes for 14.
Two upgrade changes that touch security
Major upgrades from 14 to 18 change several defaults. Two are security settings, and one of them doesn't change by itself.
CREATE on the public schema. PostgreSQL 15 removed the default CREATE permission for PUBLIC on the public schema, which is the secure pattern recommended since CVE-2018-1058. The release notes say this applies to new clusters and new databases, and that upgrading with pg_upgrade or restoring a dump keeps the old permissions. So an upgraded database still lets every role create objects in public. Check and fix it after the upgrade:
-- true means every role can still create objects in the public schema
SELECT has_schema_privilege('public', 'public', 'CREATE');
-- adopt the PostgreSQL 15+ default (grant CREATE back to the roles that need it)
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
MD5 passwords. PostgreSQL 18 deprecates MD5 password authentication and warns when you set an MD5 password. Support will be removed in a future major version. It's worth moving to SCRAM before you need to: 14.23 fixed CVE-2026-6478, which disclosed MD5-hashed passwords through a timing side channel.
-- roles that still have MD5-hashed passwords (needs superuser)
SELECT rolname FROM pg_authid WHERE rolpassword LIKE 'md5%';
-- 14 already defaults to SCRAM; this undoes an old config that set md5
ALTER SYSTEM SET password_encryption = 'scram-sha-256';
SELECT pg_reload_conf();
Each listed role then needs its password set again, and pg_hba.conf lines that say md5 can move to scram-sha-256 once every client supports it. We didn't run these SQL snippets against a server for this post. They use standard functions and catalogs documented for all supported versions.
One more note from the pg_upgrade documentation: upgrading a cluster lets the source cluster's superusers execute arbitrary code in the destination. Upgrade from a cluster you trust, and don't treat an upgrade as a way to clean up a compromised one.
Find every pinned PostgreSQL version
Database versions hide in Dockerfiles, Compose files, Helm values, Terraform and CI service containers, and the one in production isn't always the one in the repository. This script walks a repository, finds pinned PostgreSQL major versions in those files and marks each as past end of life, within 180 days of it, or supported. It uses only the Python standard library and exits with status 1 if anything is past or within 180 days of end of life:
#!/usr/bin/env python3
"""Find PostgreSQL major versions pinned in a repository and flag the ones at
or near community end of life. Looks at Dockerfiles, Compose and Kubernetes
YAML, Helm values, Terraform and CI files.
Usage: python3 pg_eol_scan.py [repo_dir]"""
import datetime as dt
import os
import re
import sys
# Final release dates from postgresql.org/support/versioning (October 2026)
EOL = {
11: dt.date(2023, 11, 9), 12: dt.date(2024, 11, 21), 13: dt.date(2025, 11, 13),
14: dt.date(2026, 11, 12), 15: dt.date(2027, 11, 11), 16: dt.date(2028, 11, 9),
17: dt.date(2029, 11, 8), 18: dt.date(2030, 11, 14),
}
PATTERNS = [
# image: postgres:14.24-alpine, FROM postgres:14, bitnami/postgresql:14.13.0
re.compile(r"(?:^|[\s\"'/=])(?:postgres|postgresql|postgis/postgis)"
r":(?P<v>\d{1,2})(?:[.\-][\w.\-]*)?(?=[\s\"']|$)"),
# Terraform: engine_version = "14.24" (aws_db_instance, aws_rds_cluster)
re.compile(r"engine_version\s*=\s*\"(?P<v>\d{1,2})(?:\.\d+)?\""),
# Cloud SQL: database_version = "POSTGRES_14"
re.compile(r"database_version\s*=\s*\"POSTGRES_(?P<v>\d{1,2})\""),
# Helm/values or CI: postgresqlVersion: 14, postgres-version: "14"
re.compile(r"(?i)postgres(?:ql)?[_-]?version[\"']?\s*[:=]\s*[\"']?(?P<v>\d{1,2})\b"),
]
# Helm values with the image split into repository: and tag: lines
TAG = re.compile(r"^\s*tag:\s*[\"']?(?P<v>\d{1,2})\.")
SUFFIXES = (".yml", ".yaml", ".tf", ".json", ".toml", ".env")
NAMES = ("Dockerfile", "Containerfile")
def scan(root, today):
hits = []
for dirpath, dirs, files in os.walk(root):
dirs[:] = [d for d in dirs if d not in (".git", "node_modules", ".terraform")]
for name in files:
if not (name.endswith(SUFFIXES) or name.startswith(NAMES)):
continue
path = os.path.join(dirpath, name)
with open(path, encoding="utf-8", errors="replace") as f:
recent = []
for n, line in enumerate(f, 1):
m = TAG.match(line)
if m and any("postgres" in r for r in recent):
major = int(m.group("v"))
if major in EOL:
hits.append((path, n, major, line.strip()))
recent = (recent + [line.lower()])[-3:]
for pat in PATTERNS:
for m in pat.finditer(line):
major = int(m.group("v"))
if major in EOL:
hits.append((path, n, major, line.strip()))
for path, n, major, line in hits:
days = (EOL[major] - today).days
if days < 0:
status = f"PAST EOL since {EOL[major]}"
elif days <= 180:
status = f"EOL {EOL[major]} ({days} days)"
else:
status = f"supported until {EOL[major]}"
print(f"{status:32} {os.path.relpath(path, root)}:{n} {line}")
return any(EOL[m] <= today + dt.timedelta(days=180) for _, _, m, _ in hits)
if __name__ == "__main__":
root = sys.argv[1] if len(sys.argv) > 1 else "."
sys.exit(1 if scan(root, dt.date.today()) else 0)
On a sample repository with a Compose file, a migration Dockerfile, Helm values and Terraform:
EOL 2026-11-12 (24 days) infra/rds.tf:3 engine_version = "14.19"
supported until 2028-11-09 infra/rds.tf:6 database_version = "POSTGRES_16"
PAST EOL since 2025-11-13 deploy/Dockerfile.migrate:1 FROM postgres:13
EOL 2026-11-12 (24 days) deploy/docker-compose.yml:3 image: postgres:14.24-alpine
supported until 2029-11-08 deploy/docker-compose.yml:5 image: "postgres:17"
EOL 2026-11-12 (24 days) deploy/values.yaml:4 tag: 14.13.0
The Terraform line pins 14.19 on RDS, which leaves RDS standard support on 31 October, before the community end of life. The migration image runs PostgreSQL 13, already a year past end of life, which is easy to miss because it only runs during deploys. The script reads what's written in the repository. For what's actually running, SELECT version(); on each server is the source of truth. The EOL table stops at 18, the newest major on the versioning page on 19 October, and the script skips majors it doesn't know. PostgreSQL 19 reached its first release candidate on 15 October, so add it to the table once the versioning page lists its end-of-life date.
Container images are where old database versions linger longest. Here's Safeguard's interactive walkthrough of scanning a container image:
What to do
- Inventory every PostgreSQL 14 instance, including CI service containers, migration and backup jobs, and read replicas, with the script above and
SELECT version();. - Apply 14.24 now and the final release when it ships. Neither ends the need to upgrade, but 14.24 fixes 24 CVEs.
- On RDS, move off 14.18 and 14.19 before 31 October, then plan the major upgrade before 28 February 2027 unless you've budgeted for Extended Support.
- Upgrade to 18, testing with
pg_upgrade --checkfirst, or use logical replication to a new cluster if you need near-zero downtime. - After the upgrade, revoke
CREATEonpublicfromPUBLICand move MD5 passwords to SCRAM. Neither happens automatically. Our post on the PostgreSQL CVE-2025-1094 response shows how quickly a PostgreSQL bug can turn into something attackers use.
The fair view
Five years of support is generous, and PostgreSQL announces its dates years in advance and sticks to them. Running 14 for a few weeks past 12 November won't suddenly break anything, and managed providers' extended support is a real option for teams that need more time. Major upgrades of large databases are hard to schedule, and a rushed one causes outages of its own.
The cost of waiting is cumulative, though. In 2026 alone, 36 CVEs needed a fix in 14. From 13 November, the next one won't get one upstream, and every month after that adds to the list of known, unfixed bugs on that server. A database upgraded in a planned window this quarter is cheaper than one upgraded in a hurry after the first bad CVE of 2027.
Check yourself
You upgraded from 14 to 18 with pg_upgrade. Can any role still create tables in the public schema?
Yes, probably. PostgreSQL 15 changed the default only for new clusters and new databases. pg_upgrade and dump restores keep the old permissions, so run SELECT has_schema_privilege('public', 'public', 'CREATE'); and revoke it if the answer is true.
Your RDS instance runs PostgreSQL 14.19. Which date comes first?
31 October 2026, when RDS ends standard support for minor versions 14.18 and 14.19. The community end of life for 14 follows on 12 November, and RDS standard support for major version 14 ends on 28 February 2027.
Why does a client-side CVE like the pg_dump overflow matter for a database upgrade?
Upgrades and migrations usually involve dumping and restoring, or connecting tools to servers you don't fully control. 14.24 fixed a heap buffer overflow in pg_dump and a way for a source server's superuser to run code in the psql restoring its dump, so use patched client tools for the migration itself.