25001ERRORTier 1 — Safe✅ HIGH confidenceactive SQL transaction
What this means
A command that cannot run inside an active transaction block (such as CREATE DATABASE, VACUUM, or certain system-administration commands) was issued while a transaction was in progress.
Why it happens
- 1CREATE DATABASE or DROP DATABASE issued inside a BEGIN...COMMIT block
- 2VACUUM, CLUSTER, or REINDEX DATABASE issued inside a transaction
- 3Calling a function that internally executes a transaction-incompatible command
- 4ORM or migration framework wrapping all DDL in transactions and using a command that is transaction-incompatible
How to reproduce
CREATE DATABASE is issued inside an explicit transaction block.
BEGIN;
CREATE DATABASE newdb; -- triggers 25001Fix 1: Issue the command outside a transaction block
Always — transaction-incompatible commands must run in autocommit mode.
-- End the current transaction first:
COMMIT; -- or ROLLBACK;
-- Then run the command in autocommit mode (no BEGIN):
CREATE DATABASE newdb;Why this works
Commands like CREATE DATABASE operate at the cluster level and manipulate the database template or global catalog entries. These operations cannot be rolled back by the transaction manager and are therefore prohibited inside transactions. Running outside a transaction means each statement is auto-committed.
Fix 2: Configure your migration tool to run the command outside a transaction
When a migration framework wraps all DDL in transactions.
-- In Flyway: use custom migration script with:
-- SET statement_timeout TO 0;
-- And mark the script as non-transactional (-- disableInTransaction in Flyway)
-- In Django migrations: use database_backwards / RunSQL with atomic=False
-- In psql, use set AUTOCOMMIT on before issuing the commandWhy this works
Most migration tools run each migration in a transaction for atomicity. For transaction-incompatible commands, the tool must be configured to suppress the BEGIN that wraps the migration. The command then executes in autocommit mode via the server's default behaviour for statements outside a transaction block.
What not to do
Wrap CREATE DATABASE in a DO block to try to bypass the restriction
Why it's wrong: The restriction applies regardless of how the command is invoked; PL/pgSQL DO blocks still run inside the calling transaction context.
Sources
📚 Official docs: https://www.postgresql.org/docs/current/errcodes-appendix.html
📚 Feature docs: https://www.postgresql.org/docs/current/sql-createdatabase.html
🔧 Source ref: src/backend/tcop/utility.c — PreventInTransactionBlock()
📖 Further reading: CREATE DATABASE
Confidence assessment
✅ HIGH confidence
Stable and well-documented. The set of transaction-incompatible commands is well-known and consistent across versions. The migration tool workaround advice is general; specific configuration varies by tool version.
See also
🔗 Related errors
📄 Reference pages