PostgreSQL error 3B000 indicates a general savepoint exception, typically occurring when attempting to rollback or release a savepoint that no longer exists. This commonly happens in ORMs when transaction state becomes desynchronized.
Error code 3B000 belongs to PostgreSQL's "Class 3B — Savepoint Exception" category and represents a general savepoint-related error. A savepoint is a named marker within a transaction that allows you to roll back all commands executed after it was established, without rolling back the entire transaction. This error occurs when your application attempts to manipulate a savepoint that no longer exists, usually because the parent transaction has already been committed or rolled back. The error is especially common in ORM frameworks (like Django, Doctrine, Ecto) that use savepoints to implement nested transactions.
Check your application code to ensure savepoints are only created and used within transaction blocks. Savepoints cannot be used outside transactions.
BEGIN;
SAVEPOINT my_savepoint;
-- Your operations here
ROLLBACK TO SAVEPOINT my_savepoint;
COMMIT;If using an ORM, verify that nested transactions are being created within an active parent transaction.
Review your PostgreSQL server logs to understand what operation preceded the error. Enable logging if not already enabled:
ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();Then check the log file (usually in /var/log/postgresql/ on Linux or the configured log directory).
If using an ORM (Django, Doctrine, SQLAlchemy, Ecto, etc.), verify the ORM's savepoint/nested transaction implementation:
Django: Ensure you're using transaction.atomic() correctly and not mixing manual savepoints with ORM nested transactions.
Doctrine/Symfony: Update to the latest version as savepoint bugs have been fixed in newer releases.
Ecto: Check that you're not attempting to rollback savepoints outside the transaction context.
Consider adding debugging logs to trace exactly which savepoint is being referenced when the error occurs.
Ensure errors are properly caught and don't leave the transaction in an aborted state. In PostgreSQL, once an error occurs in a transaction, the entire transaction becomes aborted:
BEGIN;
-- Operation that fails
-- Transaction is now aborted
ROLLBACK TO SAVEPOINT sp1; -- This will also fail
ROLLBACK; -- Reset to clean stateWrap database operations in proper exception handlers to prevent transaction corruption.
If the issue is with your ORM, check the issue tracker for known savepoint/nested transaction bugs:
- Django: https://code.djangoproject.com/ - search for savepoint issues
- Doctrine: Check GitHub issues in dmaicher/doctrine-test-bundle
- Ecto: https://github.com/elixir-ecto/ecto_sql
- Npgsql (.NET): https://github.com/npgsql/npgsql
Upgrade to the latest stable version where the bug may already be fixed.
If your application doesn't require nested transactions, consider disabling savepoint mode in your ORM configuration:
Django: Set "ATOMIC_REQUESTS": False if you don't need automatic transaction wrapping.
Doctrine: Use standard transactions instead of nested transactions if the use case doesn't require them.
This eliminates the complexity and potential for savepoint-related errors.
Savepoints can only be used within transaction blocks (BEGIN/COMMIT). In PL/pgSQL stored procedures, you cannot use explicit SAVEPOINT/ROLLBACK commands. Instead, PL/pgSQL automatically creates implicit savepoints for EXCEPTION blocks. If you have more than PGPROC_MAX_CACHED_SUBXIDS (64 by default) active subtransactions in a session, performance degradation may occur. Monitor savepoint usage in high-concurrency applications to prevent this. The error class 3B includes both 3B000 (general savepoint exception) and 3B001 (invalid_savepoint_specification) - both have similar root causes related to savepoint lifecycle management.
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL
ERROR 42501: must be owner of table
How to fix "must be owner of table" in PostgreSQL
trigger cannot change partition destination
How to fix "Trigger cannot change partition destination" in PostgreSQL
SSL error: certificate does not match host name
SSL error: certificate does not match host name in PostgreSQL
No SSL connection
No SSL connection to PostgreSQL