September 22, 2026

PostgreSQL 18.6 security release: what apt upgrade won't fix

PostgreSQL 18.6 fixes 28 vulnerabilities. Three fixes need manual reindexing after you update, and PostgreSQL 14 loses support November 12, 2026.

Insight

The PostgreSQL 18.6 security release shipped on August 13, 2026, alongside 17.11, 16.15, 15.19, 14.24, and a 19 Beta 3 preview, according to PostgreSQL's August 2026 release announcement. It's a cumulative security and bug-fix release: 28 vulnerabilities fixed, over 110 bugs closed, no dump and reload required. Run apt upgrade or let your managed database provider auto-patch, and the binary swap is done. The part that isn't done is the part no package manager performs: three specific conditions in this release need a manual reindex, and if nobody runs it, some indexes stay silently wrong.

What shipped in the August 2026 release

The release covers five supported branches (18.6, 17.11, 16.15, 15.19, 14.24) plus a preview build of the next major version. It skips one number: PostgreSQL 18.5 was never shipped, pulled before release because of a regression, so 18.4 users move straight to 18.6. The update itself is a plain minor-version bump. As the announcement puts it, "you may simply stop PostgreSQL and update its binaries." No pg_upgrade, no export and reimport, no downtime beyond a restart.

The 28 fixed vulnerabilities each get an individual CVE ID and a CVSS score, listed on PostgreSQL's security advisories page rather than in the announcement itself. That page is the place to pull per-CVE detail for a compliance record; the announcement doesn't rate severity beyond the numeric scores, and neither does this article.

That simplicity is exactly why the three follow-up items matter. A routine patch doesn't prompt anyone to go check index health afterward, and none of these three conditions announce themselves with an error.

How to apply the PostgreSQL 18.6 update

1. Apply the update

Stop PostgreSQL, replace the binaries with the new minor version, start it back up. That's the entire upgrade for anyone already on 18.x, 17.x, 16.x, 15.x, or 14.x. A standard apt upgrade, a yum patch, or a managed provider's auto-patch cycle covers this step completely. Nothing below this line happens automatically.

2. Check reltuples on tables with GIN indexes

A bug in parallel GIN index builds could leave the reltuples estimate on a table set to a bogus value, Infinity or NaN, in pg_class. That single bad number stops autovacuum and autoanalyze from ever processing the table again, and the announcement is explicit that "this situation will not self-correct." It sits broken until someone fixes it by hand.

PostgreSQL's own notes supply the check for this one:

SQL
SELECT DISTINCT t.oid::regclass, t.reltuples FROM pg_class t
JOIN pg_index i ON t.oid = i.indrelid
JOIN pg_class ic ON i.indexrelid = ic.oid
WHERE t.relhasindex AND ic.relam = 2742;

Run it after the update. Any table where reltuples reads as Infinity or NaN needs an ANALYZE to reset it. Building another index on the same table also forces a reset, if ANALYZE isn't convenient right away.

3. Reindex btree_gist indexes on float or bit columns

This one has a narrow scope, and getting the scope wrong wastes effort in one direction and leaves you exposed in the other. The announcement's own wording: "If you use btree_gist, you should reindex btree_gist indexes on float4 or float8 columns that might contain NaN values, as well as btree_gist indexes on bit or bit varying columns." That's float4 and float8 columns, where the bug affects how NaN values get handled, and bit or bit varying columns, where it affects sort order. A btree_gist index on an integer, text, or timestamp column isn't implicated by this release note at all. Don't reindex your whole btree_gist footprint on the strength of this fix; reindex the float and bit ones.

The fix is a straight REINDEX INDEX your_index_name; per affected index.

4. Reindex ltree indexes with more than roughly 14,653 labels

Separately from the btree_gist issue, ltree values with more than about 14,653 labels could compare incorrectly because of an integer overflow. The announcement says the affected indexes "may be corrupt"; the 18.6 release notes are more specific, stating that a btree index containing such values "is probably corrupt and should be reindexed after installing this update." This applies to ltree usage on its own, whether or not you're also using btree_gist.

Same command: REINDEX INDEX your_index_name; on any ltree index that clears the threshold.

5. Decide what to do about PostgreSQL 14

If you're patching PostgreSQL 14, this is the last time you'll do it before that branch goes dark. The announcement states plainly: "PostgreSQL 14 will stop receiving fixes on November 12, 2026. If you are running PostgreSQL 14 in a production environment, we suggest that you make plans to upgrade to a newer, supported version of PostgreSQL." Version 14.24 is the final scheduled release on that branch. After November 12, a new CVE against PostgreSQL 14 gets no fix, from PostgreSQL or anyone else. Teams still on 14 have roughly seven weeks from this release date to get an upgrade path onto the calendar, not necessarily executed, but at least scheduled with an owner attached.

That plan is worth coordinating with any other framework upgrades sitting in the same maintenance window. Django 6.1's own version floors, which now require PostgreSQL 15 or higher, mean a team moving off PostgreSQL 14 and a team moving off Django 6.0 are often the same team, on the same calendar.

Telling whether the btree_gist and ltree conditions apply to you

The announcement tells you the conditions but only hands you a working check for one of the three fixes, the GIN reltuples query above. For btree_gist and ltree, it says "if you use X" and leaves the applicability check to you. What follows is HighCircl's own construction, not something pulled from PostgreSQL's release notes, so treat it as a starting query to adapt rather than an official recommendation.

To find candidate btree_gist indexes on float or bit columns:

SQL
SELECT n.nspname, c.relname AS table_name, ic.relname AS index_name, a.attname, t.typname
FROM pg_index i
JOIN pg_class c ON c.oid = i.indrelid
JOIN pg_class ic ON ic.oid = i.indexrelid
JOIN pg_am am ON am.oid = ic.relam
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = ANY(i.indkey)
JOIN pg_type t ON t.oid = a.atttypid
WHERE am.amname = 'gist'
  AND t.typname IN ('float4', 'float8', 'bit', 'varbit');

For ltree, the question is simpler to ask but requires knowing your data: does any ltree column actually hold paths deep enough to exceed roughly 14,653 labels? For each ltree column, run something like SELECT max(nlevel(your_column)) FROM your_table; and compare the result against the threshold. A shallow taxonomy with a few dozen levels is nowhere near the risk zone; a deeply nested one built up over years of inserts might be.

None of this runs itself. If nobody on the team currently owns database maintenance between releases, hiring a backend developer who owns database maintenance, not just feature work closes that gap before the next cumulative release repeats it.

FAQ

Do I need to dump and reload to apply PostgreSQL 18.6?

No. This is a minor-version release. The announcement is explicit that you can stop the server, swap the binaries, and restart, with no export and reimport step.

What happens if I skip the manual reindex steps?

The announcement describes two outcomes, not a longer list. Affected ltree indexes "may be corrupt," in the announcement's words. Affected btree_gist indexes on float or bit columns risk wrong handling of NaN values or wrong sort order, depending on the column type. It doesn't characterize either as a security risk on its own; it's a correctness problem that sits in your database until you reindex.

Does this release require immediate action, or can it wait for a normal maintenance window?

The binary update itself is routine and fits any normal patch cycle. The urgency, if there is any, comes entirely from the three follow-ups, and each one is conditional: you only owe work here if you actually run parallel-built GIN indexes, btree_gist on float or bit columns, or ltree with a deep enough label count. A database with none of the three has nothing left to do after step one.

When does PostgreSQL 14 stop getting security fixes?

November 12, 2026. Version 14.24, shipped in this same release, is the last scheduled patch for that branch. Anyone running PostgreSQL 14 in production after that date is running an unpatched major version for any vulnerability discovered from then on.

Share this article

Author Image

HighCircl Editorial Team

The HighCircl editorial team writes about hiring software engineers, nearshore development, and engineering team building. Our articles draw on direct experience sourcing and placing senior developers across Poland, Hungary, Slovakia, Serbia, Slovenia, Romania, and Spain — and on candid conversations with the CTOs and engineering leads who hire them.

HighCircl is a nearshore engineering network that delivers matched candidate shortlists in 72 hours. Every piece of content we publish is informed by real engagement data: actual developer rates, real hiring timelines, and what separates engineering teams that scale cleanly from those that stall.

Take Me to the Experts

Access our network of industry-leading software engineers.

Start Now