pg_dump: error: aborting because of server version mismatch means your pg_dump is older than the PostgreSQL server it is dumping. pg_dump refuses to read a newer major version. Run a pg_dump whose major version is the server's or newer; the simplest one is the copy inside the server's own container.

The detail line names both versions. Match the first number of the pg_dump version to the server's, or go higher, and run the same command again.

The error

docker exec -e PGPASSWORD=fix4pass fix4-pg16 pg_dump -h host.docker.internal -p 15460 -U postgres postgres
pg_dump: error: aborting because of server version mismatch
pg_dump: detail: server version: 18.4 (Debian 18.4-1.pgdg13+1); pg_dump version: 16.14 (Debian 16.14-1.pgdg13+1)

Why it happens

Every major PostgreSQL release changes the system catalogs that pg_dump reads to rebuild your schema. A pg_dump knows the catalogs of its own version and of older ones, so it can dump servers older than itself, but it cannot know what a later release added, and it stops rather than write a dump that silently misses objects. The check runs before anything is read, so a database with one tiny table fails exactly like a large one.

On a developer machine the old client usually comes from somewhere else: the postgresql-client package of the Linux distribution, an older PostgreSQL installed on Windows whose bin folder is on the PATH, or a backup script in a container built on an older image, while the database itself moved to postgres:18. Here the version 16 client lived in a second container and reached the 18 server through the published port.

The fix

docker exec -e PGPASSWORD=fix4pass fix4-pg18 pg_dump -h host.docker.internal -p 15460 -U postgres -d appdb -f /tmp/appdb.sql

docker exec fix4-pg18 head -n 12 /tmp/appdb.sql
--
-- PostgreSQL database dump
--

\restrict elHoQp50Zz8FT3yBMFinUgZ1cS1U2OJi3VYvjuMTgmzdqxUK6hfquszsogDcz5n

-- Dumped from database version 18.4 (Debian 18.4-1.pgdg13+1)
-- Dumped by pg_dump version 18.4 (Debian 18.4-1.pgdg13+1)

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;

Same server, same host and port, only the client changed: the dump ran and its header records both versions as 18.4. fix4-pg18, fix4-pg16, the port and the password are the test's own. The \restrict line holds a random key that recent pg_dump releases write into plain-text dumps, so that psql blocks backslash commands hidden in the data while it restores the file. The other direction works: the 18 client dumped the 16 server in the same test without complaint. If you cannot run the server's container, install the client package of the server's major version from the PostgreSQL project's own repositories and call that pg_dump by its full path.

How it was reproduced

Two containers on Docker Desktop 4.91.0 under Windows 11: postgres:18 (server and tools 18.4) published on port 15460, and postgres:16 used only for its pg_dump 16.14. The 16 client reached the 18 server through host.docker.internal and failed as shown; the 18 client, run with the same host, port and user, wrote a 79-line dump of a small test database.

Frequently asked

Can an older pg_dump back up a newer PostgreSQL server?
No. pg_dump refuses to dump a server of a newer major version and stops with aborting because of server version mismatch. A newer pg_dump can dump older servers.
How do I run pg_dump for a PostgreSQL Docker container?
Use the pg_dump inside the server's container, for example docker exec with the container name and pg_dump, so the client always matches the server image. Give pg_dump -f with a path inside the container, as in the fix above.
Which pg_dump version should I use?
The same major version as the server, or newer. The detail line of the error prints both versions, so compare the first number of each.

More decoded errors in the Fixes category. For dump formats, restore and scheduling, see PostgreSQL backup and restore for SQL Server DBAs.