PostgreSQL standby server fails to start in hot standby mode when its max_connections setting is lower than the primary server. This occurs because the standby needs to allocate internal structures (KnownAssignedXIDs and lock tables) large enough to handle the maximum snapshot from the primary.
In PostgreSQL streaming replication, a hot standby allows read-only queries while the standby server recovers WAL (write-ahead log) records from the primary. However, PostgreSQL requires the standby server to have a max_connections value that is equal to or greater than the primary server's setting. This safety check exists because the standby must maintain internal structures (KnownAssignedXIDs array and the lock table) that are sized based on max_connections. If the standby's max_connections is too low, these structures cannot accommodate the maximum possible snapshot from the primary, which could cause crashes or unpredictable behavior during recovery. When the standby encounters a primary with a higher max_connections value, it will either pause recovery (if hot_standby is enabled) or shut down immediately (if hot standby is disabled), preventing the standby from starting until the configuration is corrected.
Connect to both the primary and standby PostgreSQL instances and verify their current max_connections settings.
# On primary
psql -U postgres -c "SHOW max_connections;"
# On standby
psql -U postgres -c "SHOW max_connections;"Note the values for comparison. The standby value must be >= the primary value.
Before making configuration changes, stop the standby server to prevent conflicts:
sudo systemctl stop postgresql
# Or if using pg_ctl:
sudo -u postgres /usr/lib/postgresql/VERSION/bin/pg_ctl stop -D /var/lib/postgresql/VERSION/mainWait for it to shut down completely.
Edit the standby's postgresql.conf file (usually at /etc/postgresql/VERSION/main/postgresql.conf or /var/lib/postgresql/VERSION/main/postgresql.conf) and update the max_connections parameter:
# Edit the file
sudo nano /etc/postgresql/VERSION/main/postgresql.conf
# Find the line with max_connections and change it to match or exceed the primary
max_connections = 200 # Set to at least the primary's valueIf the line is commented out, uncomment it. Ensure there are no spaces before the parameter name.
Restart the PostgreSQL service on the standby:
sudo systemctl start postgresql
# Or:
sudo -u postgres /usr/lib/postgresql/VERSION/bin/pg_ctl start -D /var/lib/postgresql/VERSION/mainMonitor the startup logs to confirm recovery proceeds without errors.
Confirm the standby is now in hot standby mode and accepting read-only connections:
# Check if standby is accepting connections
psql -U postgres -c "SELECT version();"
# Verify hot_standby is enabled
psql -U postgres -c "SHOW hot_standby;"
# Check max_connections is now set correctly
psql -U postgres -c "SHOW max_connections;"You should see hot_standby = on and max_connections matching the primary.
Verify that replication is progressing normally and the standby is caught up:
# On primary, check replication slots and lag
psql -U postgres -c "SELECT slot_name, active, restart_lsn FROM pg_replication_slots;"
psql -U postgres -c "SELECT client_addr, write_lag, flush_lag, replay_lag FROM pg_stat_replication;"If lag is increasing or replication appears stuck, check PostgreSQL logs for additional errors.
For cascading replication (standby feeding other standbys), ensure all servers in the chain have max_connections set to at least the highest value in the chain, not just their direct upstream.
When using patroni or other high-availability frameworks, max_connections changes typically require template modification since these tools manage configuration. Check your HA tool's documentation for the proper procedure.
Note that increasing max_connections requires restarting PostgreSQL, which interrupts all connections. Plan this maintenance during a low-traffic window. The parameter cannot be changed via RELOAD and requires a full restart.
If you have WAL archive recovery paused and need to resume, the standby may show "If recovery is unpaused, the server will shut down" — this is normal and expected. After increasing max_connections and restarting, recovery will automatically resume.
For very large deployments, also review max_wal_senders (max concurrent replication connections) and max_replication_slots, which must accommodate all standby servers and should not exceed max_connections.
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL
ERROR 42501: must be owner of table
How to fix "must be owner of table" in PostgreSQL
trigger cannot change partition destination
How to fix "Trigger cannot change partition destination" in PostgreSQL
SSL error: certificate does not match host name
SSL error: certificate does not match host name in PostgreSQL
No SSL connection
No SSL connection to PostgreSQL