Skip to content

3B001 — invalid_savepoint_specification

PostgreSQL SQLSTATE 3B001: missing savepoints, transaction state, and recovery.

3B001 — invalid_savepoint_specification

At a glance

3B001 means that a savepoint operation named a savepoint that is absent at the current transaction level. It is different from 25P01, which means there is no active transaction block at all.

Field Value
SQLSTATE 3B001
Condition invalid_savepoint_specification
Status active
Known present by 8.0.0
Locked snapshots 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3
Macros ERRCODE_S_E_INVALID_SPECIFICATION
Aliases

Meaning

The transaction manager raises 3B001 when ROLLBACK TO SAVEPOINT or a related savepoint operation cannot find the requested name in the current savepoint stack. PostgreSQL 18’s source template includes the name; the PG10 source uses the older no such savepoint wording. The missing name is a transaction-structure problem, not a table-data conflict.

Diagnosis

Capture SQLSTATE, primary message, transaction status, and the exact savepoint sequence. Check spelling, whether a savepoint was released, and whether a nested procedure or subtransaction changed the current savepoint level. After an ERROR inside an explicit block, the connection is INERROR; do not issue catalog or repair SQL there before rollback.

Response

Rollback the failed block, begin a new explicit transaction, and establish a savepoint whose name and nesting are known. If partial work should survive, use a correctly named savepoint before the risky statement and ROLLBACK TO that existing marker; a missing marker cannot be reconstructed after the error. Treat a retry as a new transaction plan and preserve the application’s normal idempotency checks.

Messages

18.6’s fixed source has savepoint "%s" does not exist and a related current-level variant. The selected PG10 output is no such savepoint. These are source-confirmed version/call differences; branch on 3B001 and transaction state rather than a single English message.

Representative case

verify/cases/3B001/snippets.json (SHA-256 595ce7692e34d36cc31df94c65c7040ee9bc4558fa887c23b56ba3187d235deb) contains an explicit BEGIN, an existing present savepoint, a ROLLBACK TO SAVEPOINT missing, and a rollback/repaired sequence. See the public case export and structured evidence.

BEGIN;
SAVEPOINT present;
ROLLBACK TO SAVEPOINT missing;
ROLLBACK;
BEGIN;
SAVEPOINT present;
RELEASE SAVEPOINT present;
COMMIT;

The runner uses autocommit only to make each registry BEGIN/ROLLBACK/COMMIT boundary explicit. It asserts INERROR after the missing marker and IDLE after the recovery commit.

The selected case observed 3B001 on PostgreSQL 18.6 and 10.21. PostgreSQL 18 reported savepoint "missing" does not exist; PostgreSQL 10 reported no such savepoint. Both left the explicit block INERROR until ROLLBACK, after which a valid savepoint sequence committed.

Versions

The catalogue records 3B001 from its 8.0.0-or-earlier boundary through the formal snapshots. The selected 18.6 and 10.21 runs demonstrate the SQLSTATE and recovery boundary, while the primary message changed from the older generic wording to a named-savepoint template.

See 3B000 savepoint exception for the class definition and 25P01 no active transaction when no transaction block exists.

Sources

  • src.errcodes.18.6 (SHA-256 6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)
  • src.xact.18.6 (SHA-256 75b012c0b047d1dc905a30975c244beec366e45eac0dbf109fd21bcd611a8e39)
  • src.xact.10.23 (SHA-256 9120bd418bd0f18e3f1065a3772c92ff68f3be54e1a8c6d415043197f6daa47c)
  • SAVEPOINT documentation · local call scan src.calls.REL_18_6 (SHA-256 9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)