Incident brief
GET STACKED DIAGNOSTICS outside a handler
GET STACKED DIAGNOSTICS reads details of the exception currently being handled, so it is only valid inside an EXCEPTION handler; using it elsewhere raises this diagnostics exception.
What lands in your log
ERROR: GET STACKED DIAGNOSTICS cannot be used outside an exception handler
In 10 seconds
- What triggers it
- Call GET STACKED DIAGNOSTICS in PL/pgSQL code that is not inside an EXCEPTION handler.
- Fix
- Move the GET STACKED DIAGNOSTICS into an EXCEPTION ... handler block.
- Proof
- Reproduced on PostgreSQL 18.4 → A DO block reproduces SQLSTATE 0Z002; GET STACKED DIAGNOSTICS outside a handler is rejected, naming the statement in the CONTEXT.
Fix
What to do right now
Application-level steps for this error.
- Move the GET STACKED DIAGNOSTICS into an EXCEPTION ... handler block.
- Use GET CURRENT DIAGNOSTICS (not STACKED) if you need diagnostics outside a handler.
-- Read stacked diagnostics only inside an EXCEPTION handler.
DO $$ DECLARE msg text; BEGIN BEGIN RAISE EXCEPTION 'boom'; EXCEPTION WHEN others THEN GET STACKED DIAGNOSTICS msg = MESSAGE_TEXT; RAISE NOTICE 'caught: %', msg; END; END $$;For this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
GET STACKED DIAGNOSTICS outside a handler comes from PL/pgSQL control flow. Inspect the exact stored function body and line reported in CONTEXT before changing server settings.
Stored PL/pgSQL source for the failing function
Replace the function signature from CONTEXT; this preserves overload identity.
SELECT pg_get_functiondef(to_regprocedure('<schema.function(argument_types)>'));PL/pgSQL assertion setting
Relevant to assertion failures; harmless context for the other PL/pgSQL control-flow errors.
SELECT current_setting('plpgsql.check_asserts', true) AS plpgsql_check_asserts;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual, not paraphrased.
PostgreSQL 18 Documentation, Appendix A. PostgreSQL Error Codes (Table A.1, Class 0Z, Diagnostics Exception)
0Z002 → stacked_diagnostics_accessed_without_active_handlerRead the full section on postgresql.org →
Reading stacked diagnostics with no active handler
GET STACKED DIAGNOSTICS only works while an exception is being handled, so calling it outside a handler raises 'cannot be used outside an exception handler'.The session continues normally
GET STACKED DIAGNOSTICS failed as a standalone call outside a transaction, so session B's next statement is unaffected.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.
- 1Call GET STACKED DIAGNOSTICS in PL/pgSQL code that is not inside an EXCEPTION handler.
- 2PL/pgSQL finds there is no active exception to read diagnostics from.
- 3The statement aborts with SQLSTATE 0Z002.
Error-inspection code called GET STACKED DIAGNOSTICS in the main body instead of inside the EXCEPTION block, so there was no exception to read.
-- The error is self-contained in one statement; no schema is required.
SELECT 'no schema needed' AS setup_note;DO $$ DECLARE msg text; BEGIN GET STACKED DIAGNOSTICS msg = MESSAGE_TEXT; END $$;SELECT 'ok' AS session_after_error;What PostgreSQL actually returned
setup_note
------------------
no schema needed
(1 row)ERROR: GET STACKED DIAGNOSTICS cannot be used outside an exception handler
CONTEXT: PL/pgSQL function inline_code_block line 1 at GET STACKED DIAGNOSTICS session_after_error
---------------------
ok
(1 row)The diagnostics read succeeds once it runs inside an EXCEPTION handler.
Without this
Before: reading diagnostics with no handler aborts
With this, tested
After: the handler makes diagnostics available
- A second operational test: exact SQL, raw output, measured result, and engineer notes
Card required. Cancel before day 7 and you are not charged.
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.
Verification
- Last verified
- 2026-07-24 (isolated lab, PostgreSQL 18.4)
- Verification scope
- Verified against PostgreSQL 18.4 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.