{
  "id": 12151684,
  "title": "Postgres 16 18: Why You Can't Just Swap the Image",
  "url": "https://urgent.news/2026/10/05/postgres-16-18-why-you-cant-just-swap-the-image",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-05T12:44:42.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/dwoitzik/postgres-16-18-why-you-cant-just-swap-the-image-1j4j"
  },
  "original_language": "en",
  "account": "PostgreSQL major version upgrades are not as simple as changing the image tag in a Kubernetes Deployment. When migrating from PostgreSQL 16 to PostgreSQL 18, several key differences exist that require careful planning and execution. The data directory format changes between versions, system catalogs are incompatible, and extensions need to be rebuilt. CNPG (CloudNativePG), a CloudNative PostgreSQL distribution, faced challenges during their upgrade from PG16 to PG18.\n\nThe migration process involved creating a fresh PostgreSQL 16 cluster first, then updating the image to PostgreSQL 18 after the data was restored. This ensured that the PVC and the operator were aligned with the initial state. However, several issues arose during the process.\n\nFirstly, PostgreSQL stores data in a format specific to its major version. The PG_VERSION file in the data directory indicates which version created it. When PostgreSQL 18 started and found PG\\_VERSION = 16, it refused to start, citing a data directory with incorrect ownership.\n\nSecondly, pg\\_upgrade, the official tool for in-place major version upgrades, is not a viable option on Kubernetes. CNPG manages the data directory through its operator, and manual modifications are reverted. Additionally, the PVC is bound to the cluster definition, and changing the PostgreSQL version in the configuration doesn't automatically upgrade the data.\n\nThe recommended migration path is dump-and-restore, rather than an in-place upgrade. The steps involved dumping the database from PostgreSQL 16, creating a fresh PostgreSQL 18 cluster, restoring the dump into the new cluster, and updating Authelia to use the new PostgreSQL 18 connection string. However, a role discovery bug arose during the restore process, where a leftover role from the original CNPG cluster initialization was not present in the pg\\_dump output.\n\nTo address these challenges, it is crucial to create a fresh PVC (Persistent Volume Claim) when migrating between major PostgreSQL versions. This ensures that the data directory is empty, allowing PostgreSQL 18 to create its own data directory format and populate it with the restored data during pg\\_restore. Additionally, CNPG offers a backup and restore feature that includes operator roles, eliminating the need for manual role recreation. Using CNPG's backup and restore functionality could simplify the migration process and minimize the risk of data loss.",
  "summary": "Originally published at woitzik.dev Disclosure: This post contains Amazon affiliate links (marked with *). If you buy through them, I earn a small commission at no extra cost to you. I only link gear I actually own and use daily. PostgreSQL major version upgrades are not swap-the-image operations. You can't change postgres:16 to postgres:18 in a Deployment and expect it to work. The data…",
  "key_points": [
    "PostgreSQL major version upgrades require careful planning and execution.",
    "Data directory format changes between PostgreSQL 16 and 18 versions.",
    "CNPG faced challenges during PG16 to PG18 upgrade, recommending dump-and-restore method."
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}