select open change scope Open full search

PG.CENTER connects PostgreSQL documentation, reference, and ecosystem knowledge. Maintained by Pigsty.

SQLSTATE / CLASS 3B · SAVEPOINT EXCEPTION

invalid_savepoint_specification

SQLSTATE
3B001
Condition name
invalid_savepoint_specification
Class
Savepoint Exception
Source macro
ERRCODE_S_E_INVALID_SPECIFICATION
Evidence
Observed at runtime in the source evidence
Analysis & operational context

English SQLSTATE atlas: authored explanations and source/runtime evidence are separate from the manual definitions. View source ↗

<h1>3B001 — invalid_savepoint_specification</h1>

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.

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.

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)

Source evidence

Evidence belongs to the frozen source and runtime versions listed here. It is not a runtime verification of the selected manual version.

3B001 is the invalid_savepoint_specification condition in Class 3B.

Method: Read the fixed errcodes.txt row and macro mapping.

Limits: The class-level 3B000 entry is separate from this specific condition.

src.errcodes.18.6

RollbackToSavepoint emits a missing-savepoint error when the named savepoint is not present at the current level.

Method: Trace ERRCODE_S_E_INVALID_SPECIFICATION in xact.c.

Limits: PG10 uses the older no such savepoint wording; the SQLSTATE and state transition are the stable facts here.

src.xact.18.6 src.calls.REL_18_6

A failed ROLLBACK TO SAVEPOINT leaves the explicit transaction in error; ROLLBACK ends that block before a new savepoint sequence.

Method: Run the shared explicit BEGIN/SAVEPOINT/ROLLBACK case and inspect transaction status.

Limits: A valid savepoint at another nesting level is a different case.

doc.savepoint.18.6

The selected 3B001 case passed on PostgreSQL 18.6 and 10.21 with the structured SQLSTATE, transaction-state, and repair assertions recorded in the runtime entries.

Method: Read the selected runner summaries and raw outputs tied to the shared snippet registry.

Limits: This covers the selected mechanism only, not all source callers or all driver/pool behavior.

runtime.3B001-batch34-20260909.latest runtime.3B001-batch34-20260909.pg10

Message templates

ERROR · message.savepoint-modern

Primary

savepoint "%s" does not exist

The name is dynamic.

ERROR · message.savepoint-pg10

Primary

no such savepoint

PG10 wording omits the savepoint name.

Reproduction & repair cases

invalid_savepoint_recovery · PG 10, 18

Preconditions

  • A runner-owned disposable target is provisioned.

Trigger: Inside a valid explicit transaction, roll back to a savepoint name that was never established, then rollback and establish a valid savepoint.

Expected assertions

  • SQLSTATE is 3B001
  • The diagnostic identifies the missing savepoint
  • The failed block is INERROR until ROLLBACK
  • A valid SAVEPOINT/RELEASE/COMMIT succeeds afterward

Repair: Verify the savepoint name and nesting level; rollback the failed block before issuing a new savepoint sequence.

Cleanup: Drop the case schema with an owner connection.

Recorded runtime evidence

18.6 (Homebrew) · passed

Run: 3B001-batch34-20260909

{
  "repair": {},
  "primary": "savepoint \"missing\" does not exist",
  "severity": "ERROR",
  "sqlstate": "3B001",
  "statuses": {
    "after_error": "INERROR",
    "after_repair": "IDLE",
    "after_rollback": "IDLE"
  },
  "connection_autocommit": true
}
10.21 (Debian 10.21-1.pgdg90+1) · passed

Run: 3B001-batch34-20260909

{
  "repair": {},
  "primary": "no such savepoint",
  "severity": "ERROR",
  "sqlstate": "3B001",
  "statuses": {
    "after_error": "INERROR",
    "after_repair": "IDLE",
    "after_rollback": "IDLE"
  },
  "connection_autocommit": true
}

Definition snapshot: english-manuals:46b7d4c661cc272f8fa78ece502… · English manual source