Incident brief
ROLLBACK TO an undeclared savepoint
ROLLBACK TO SAVEPOINT (or RELEASE SAVEPOINT) fails if the named savepoint was never established in the current transaction, raising this savepoint exception.
What lands in your log
ERROR: savepoint "before_charge" does not exist
In 10 seconds
- What triggers it
- Open a transaction and issue ROLLBACK TO SAVEPOINT <name> without having declared that savepoint.
- Fix
- Declare the savepoint (SAVEPOINT <name>) before rolling back to it.
- Proof
- Reproduced on PostgreSQL 18.4 → Inside a transaction the reproduction rolls back to a savepoint that was never declared, raising SQLSTATE 3B001.
Fix
What to do right now
Application-level steps for this error.
- Declare the savepoint (SAVEPOINT <name>) before rolling back to it.
- Match every ROLLBACK TO or RELEASE to a savepoint actually established earlier in the transaction.
-- Establish the savepoint before rolling back to it.
BEGIN;
SAVEPOINT before_charge;
ROLLBACK TO SAVEPOINT before_charge;
COMMIT;For this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
Savepoints are transaction- and connection-local and are discarded by transaction end. Verify the pool did not switch connections and replay SAVEPOINT before ROLLBACK TO.
Current backend and transaction
Record backend PID/xid around SAVEPOINT and ROLLBACK TO; a PID change proves pool connection switching.
SELECT pg_backend_pid() AS backend_pid,
txid_current_if_assigned() AS current_xid,
current_setting('transaction_isolation') AS isolation;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 3B, Savepoint Exception)
3B001 → invalid_savepoint_specificationRead the full section on postgresql.org →
Rolling back to a missing savepoint
No SAVEPOINT before_charge was established in this transaction, so ROLLBACK TO raises 'savepoint before_charge does not exist'.Recovering the aborted transaction
Since ROLLBACK TO ran inside an open transaction, the whole transaction is left aborted, session B must issue ROLLBACK before starting fresh.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.
- 1Open a transaction and issue ROLLBACK TO SAVEPOINT <name> without having declared that savepoint.
- 2PostgreSQL looks for the named savepoint in the current transaction and finds none.
- 3The statement aborts with SQLSTATE 3B001: 'savepoint does not exist'.
Error-handling code rolled back to a savepoint name that a skipped branch never actually created.
-- The error is self-contained in one statement; no schema is required.
SELECT 'no schema needed' AS setup_note;BEGIN;
ROLLBACK TO SAVEPOINT before_charge;ROLLBACK;
SELECT 'ok' AS session_after_rollback;What PostgreSQL actually returned
setup_note
------------------
no schema needed
(1 row)BEGIN
ERROR: savepoint "before_charge" does not existROLLBACK
session_after_rollback
------------------------
ok
(1 row)The rollback-to-savepoint works once the savepoint is declared first.
Without this
Before: rolling back to a missing savepoint aborts
With this, tested
After: declare then roll back
- 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.