SQLSTATE 25001Severity lowLab verified

Incident brief

Active SQL transaction

VACUUM (and a few other commands) refuse to run while a transaction block is still open. PostgreSQL rejected the command instead of running it partway.

What lands in your log

ERROR: VACUUM cannot run inside a transaction block

Reproduced on PostgreSQL 16.14Verified 2026-07-16 (Docker lab, PostgreSQL 16.14)Verified against PostgreSQL 16.14 in an isolated lab environment

In 10 seconds

What triggers it
BEGIN a transaction.
Fix
Run VACUUM on its own, outside any BEGIN/COMMIT block (plain autocommit mode).
Proof
Reproduced on PostgreSQL 16.14 → Running VACUUM inside an open transaction was rejected with SQLSTATE 25001. The session was unaffected afterward.

Fix

What to do right now

Application-level steps for this error.

  • Run VACUUM on its own, outside any BEGIN/COMMIT block (plain autocommit mode).
  • The same restriction applies to other commands too, such as CREATE DATABASE, see the premium test.
  • Wrapping VACUUM in a PL/pgSQL DO block does not get around the restriction, see the counterexample.
Fix SQL
VACUUM;

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.

Open in the interactive map →

Verification

PG 16.14
Last verified
2026-07-16 (Docker lab, PostgreSQL 16.14)
Verification scope
Verified against PostgreSQL 16.14 in an isolated lab environment
Audit status
reviewed
ShareLinkedInX

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.

FollowSubstackLinkedInnew errors · lab notes · hiring loops