Incident brief
Cannot change runtime parameter
A session tried to SET a parameter that can only be changed by restarting the server. PostgreSQL rejected the SET instead of silently ignoring it.
What lands in your log
ERROR: parameter "max_connections" cannot be changed without restarting the server
In 10 seconds
- What triggers it
- Run SET max_connections = 200; inside an ordinary session.
- Fix
- Use ALTER SYSTEM SET to write the new value, then actually restart the server, reloading the config file (pg_reload_conf()) is not enough for a postmaster-context parameter.
- Proof
- Reproduced on PostgreSQL 16.14 → SET max_connections = 200; inside a session was rejected with SQLSTATE 55P02, because max_connections is a postmaster-context parameter.
Fix
What to do right now
Application-level steps for this error.
- Use ALTER SYSTEM SET to write the new value, then actually restart the server, reloading the config file (pg_reload_conf()) is not enough for a postmaster-context parameter.
- Don't assume pg_reload_conf() returning true means the change took effect, see the premium counterexample for proof it doesn't, for this parameter.
ALTER SYSTEM SET max_connections = 150;
-- then actually restart the server (not just pg_reload_conf())For this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
max_connections has postmaster context. Confirm pending_restart and the source file/value before scheduling a restart.
Pending restart for connection settings
Show active value, configured source, and whether a restart is still required.
SELECT name, setting, context, source, sourcefile, sourceline, pending_restart
FROM pg_settings
WHERE name IN ('max_connections','superuser_reserved_connections','reserved_connections')
ORDER BY name;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual, not paraphrased.
PostgreSQL 16 Documentation, The pg_settings View, "context" column
postmaster: These settings can only be applied when the server starts, so any change requires restarting the server.Read the full section on postgresql.org →
The rejected SET
Per the manual, a postmaster-context parameter can only be applied at server start, SET rejects any attempt to change it from a running session with SQLSTATE 55P02.Confirming the session still works
The rejected SET didn't affect the session, the next statement ran normally.Reproduce & verify
A real, single-session PostgreSQL reproduction
A literal transcript of SQL run against a live PostgreSQL instance in an isolated lab. The commands below are exactly what was executed.
- 1Run SET max_connections = 200; inside an ordinary session.
- 2SQLSTATE 55P02 is reported; the setting is unchanged.
One client: SET attempted against a postmaster-context parameter.
SELECT name, setting, pending_restart FROM pg_settings WHERE name = 'max_connections';SET max_connections = 200;SELECT 1 AS session_still_alive;What PostgreSQL actually returned
name | setting | pending_restart
-----------------+---------+-----------------
max_connections | 100 | f
(1 row)ERROR: parameter "max_connections" cannot be changed without restarting the server session_still_alive
---------------------
1
(1 row)The deeper lab audit for this error
- Fix that looks like it worked but didn't: exact SQL, output, and verdict
- A manual-grounded production interpretation of the lab result
Card required. Cancel before day 7 and you are not charged.
Runbook to fix this
Runbooks for this incident
Full step-by-step fixes for the condition behind this error: the diagnosis, the exact SQL, and output captured in the lab.
- Survive a connection storm when there is no poolerConnections pile up, the app times out, and CPU is high while throughput sits flat.Free
- Catch queries spilling to temp filestemp_bytes keeps climbing and no one can name the query writing it.Pro
- Find out whether pg_stat_statements is lying to youThe slow-query dashboard is empty, or the query you are hunting is not in it.Pro
Connected
Everything this error touches
Every page this SQLSTATE connects to: the concept that explains it, the runbooks that fix it, the parameters you tune to prevent it, and the sibling errors it travels with. All real cross-references. Jump straight in, or open the full interactive map.
Fix it — runbooks
Survive a connection storm when there is no poolerFind out whether pg_stat_statements is lying to youReclaim WAL held by an inactive replication slotRejoin a demoted primary with pg_rewindRight-size synchronous_commit for latencyRight-size work_mem for hash aggregatesStop a logical slot on a quiet database pinning WALStop an abandoned slot from filling the diskStop disk-spilled sorts by tuning work_memCatch queries spilling to temp filesFind tables autovacuum keeps skippingFix random_page_cost for SSD storageFlatten checkpoint I/O spikes by tuning checkpointsHelp the planner with effective_cache_sizeMeasure freeze debt before autovacuum forces your handProve your WAL archive can actually restoreReduce WAL volume with wal_compressionSize WAL with max_wal_size and checkpoint_timeoutSpot checkpoint write pressure before it hurtsSwitch to archive_library without stopping archivingTame autovacuum on a high-churn tableWhy parallel query did not kick inRelated errors
Verification
- Last verified
- 2026-07-16 (Docker lab, PostgreSQL 16.14)
- Verification scope
- Verified against PostgreSQL 16.14 in an isolated lab environment
- Audit status
- reviewed
Went further?
Pro unlocks the second lab proof
Free page stops the bleeding. Pro adds the operational test, SQLSTATE audit, and deeper evidence, same error, more certainty.