PostgreSQL 18.6 needs an upgrade record beyond the binary version
August's update fixes 28 vulnerabilities and several defects that leave persistent state behind. Logical decoding configuration, affected encrypted data and indexes can require work after installing the binaries.
PostgreSQL's August 13 update closes 28 security vulnerabilities and fixes more than 110 bugs. The announcement lists PostgreSQL 18.6, 17.11, 16.15, 15.19 and 14.24, alongside PostgreSQL 19 Beta 3. Version 18.5 did not ship because the project found a regression. For a production operator, however, the most consequential detail is that installing the corrected binaries can leave additional work involving configuration or previously stored data.
I have run PostgreSQL in production for decades and still choose it by default for relational systems. One reason is that the project documents operational exceptions in enough detail to act on them. This release needs that attention. I would record the applicable follow-up work separately from the package deployment, because some of the defective state cannot correct itself and some existing configurations need an explicit addition.
Logical decoding gains an explicit library list
The 18.6 release notes introduce output_plugin_libraries as part of the fix for CVE-2026-6471. Previously, a replication user could select any loadable library for logical decoding. The new parameter restricts that choice to an allowed set. Its default contains the PostgreSQL-supplied output plugins pgoutput and test_decoding.
An installation using another output plugin must add it to the setting after updating. The release notes give the following example, where the additional name stands for a trusted decoder required by that installation.
output_plugin_libraries = 'pgoutput, test_decoding, my_trusted_decoder'
I would identify the decoder actually in use before deploying this change. That creates a concrete configuration review task alongside the security update. Copying the example without replacing its illustrative plugin name would not describe the installation's dependency. The new restriction is useful precisely because the administrator has to identify which additional libraries are intended to be loadable through this route.
The setting also matters during a major upgrade. When migrating from version 17 or later, pg_upgrade --check fails if the target cluster's allowed list does not permit plugins used by the source cluster's logical replication slots. The release notes direct operators to make the necessary additions on the target before the upgrade. I would include this dependency in a rehearsal, so the check establishes something about the real plugin set.
Some pgcrypto data was never properly encrypted
CVE-2026-14663 concerns pgcrypto PGP encryption when OpenSSL rejects the requested cipher. Examples in the notes include configurations using FIPS mode or lacking the legacy provider. Previously, pgcrypto failed to notice the rejection and combined the unencrypted block with the plaintext using XOR. The notes describe the result as trivially breakable. Replacing the binary prevents that behavior from continuing, but does not retrospectively encrypt affected messages.
The documented cases typically involve deprecated or non-FIPS algorithms such as Blowfish, Twofish, CAST5 or 3DES. The corrected code normally refuses to decrypt affected messages. That refusal is a consequence an operator may see after the upgrade, so I would review the encryption configuration and relevant data before assuming that a decryption failure means the update damaged valid ciphertext.
The project adds ignore-cipher-failure to the PGP decryption functions so operators can recover affected data and then encrypt it correctly. This is a recovery option with a specific purpose. The release notes require OpenSSL's behavior to match the environment in which the faulty messages were created, including which algorithms are unsupported. If that set differs, the recovery approach will not work as described.
I would keep the affected records and the recovery environment identifiable throughout that work. The intended outcome is properly re-encrypted data, with evidence of which messages needed repair. Merely making the application read the old wrapper again would leave the original confidentiality problem unresolved. The release notes' distinction between removing the faulty wrapper and re-encrypting the content is essential to planning this task.
GIN builds can leave maintenance permanently disabled for a table
A correctness fix addresses the row estimate stored in pg_class.reltuples after a parallel GIN index build. A parallel worker could report an uninitialized row count, leaving values such as infinity or NaN. According to the release notes, those values can prevent autovacuum and autoanalyze from deciding that the table needs processing. The condition does not self-heal.
The project supplies a query for finding tables with GIN indexes and inspecting their row estimates. I would run this assessment against the relevant databases after the update, then investigate unreasonable results in context.
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;
For a table with an incorrect value, the notes prescribe ANALYZE or creation of another index to reset it. The critical operational point is that future corrected index builds do not repair a bad estimate already stored by an earlier build. A server can report the new version while an affected table still has the value that prevents ordinary maintenance from processing it.
This is the kind of follow-up I would give an explicit completion record. I would retain the assessment result and identify tables that needed repair. That would let another operator distinguish a database that was checked and needed no action from one where the post-update assessment has not happened. The distinction matters because waiting for automatic maintenance is specifically insufficient for this fault.
Index repairs depend on the extension and data type
The announcement identifies separate fixes involving btree_gist and ltree. For btree_gist, the problems include NaN handling for floating-point columns and incorrect sorting of bit-string values during index building. It recommends reindexing affected indexes on float4 or float8 columns that may contain NaN, and indexes on bit or bit varying columns. That is a defined set of cases to investigate, not an instruction to rebuild every index in the cluster.
For ltree, an integer overflow could produce incorrect comparisons for values containing more than about 14,653 labels. The announcement warns that B-tree indexes over such values may be corrupt and should be reindexed. I would first identify whether the extension and that kind of data are present. The published threshold provides a concrete basis for deciding which indexes need attention.
Reindexing belongs after installation of the corrected code. Otherwise, a rebuild would still use the implementation whose behavior caused the problem. I would plan the affected index work with the application's maintenance requirements in mind and use the release's prescribed repair for the relevant case. A broad rebuild without identifying the defect would give less useful evidence about what the upgrade actually corrected.
Client scripts and role changes also need representative tests
The security fixes extend beyond server-side memory errors. CVE-2026-6464 changes how psql handles inline data after a scripted COPY FROM STDIN command that fails before copy mode starts. Previously, it could interpret the following data as commands. The corrected client recognizes a syntactically valid copy command and skips the inline data even when the server does not enter copy mode.
The notes say test scripts intentionally exercising failed copy commands may need a \. data terminator after each command. I would preserve those negative tests and adjust their framing to match the corrected parser behavior. Removing the test because its failure changed would lose coverage of the error handling that this security fix is intended to improve.
CVE-2026-14666 corrects cached plans whose row-security behavior depends on role state. Role membership, role attribute and database ownership changes can alter the expected policy behavior. Previously, PostgreSQL could continue using a plan built under the earlier state. I would include relevant role-change cases in application testing, retaining session behavior where cached plans matter rather than testing only new connections.
The release also fixes a serializable conflict-detection race involving an initially empty B-tree index. A conflict could go unnoticed and allow conflicting transactions to commit. For an application depending on serializable isolation, this reinforces the value of retaining meaningful concurrency tests through maintenance upgrades. The announcement establishes the particular defect, without providing a basis to claim that every observed concurrency anomaly has the same cause.
Replication validation deserves attention on older branches too. The announcement highlights a self-deadlock affecting PostgreSQL 14, 15 and 16 when a standby replays WAL from an older minor version. That branch-specific scope is useful when choosing regression tests. I would preserve the primary and standby version information with the result, since testing only equal-version servers would omit the configuration described in the release announcement.
Minor-version updates remain cumulative and do not require a dump and reload or pg_upgrade. For this update, I would accompany the binary version record with the applicable plugin configuration and the results of the persistent-state checks. Where a data recovery or index repair was necessary, I would record its completion separately so the next maintenance decision starts from an accurate account of the database.