SQLSTATE 25001 ERROR Class 25: Invalid Transaction State

active_sql_transaction REINDEX CONCURRENTLY cannot run inside a transaction block — 25001

PostgreSQL error "REINDEX CONCURRENTLY cannot run inside a transaction block" (SQLSTATE 25001): what it means, common causes, and how to fix it.

PG 12, 13, 14, 15, 16, 17, 18 Official docs
Last reviewed May 2025 Grounded in source

Diagnostic Queries

Symptoms

REINDEX … CONCURRENTLY was issued inside a transaction block. Like other concurrent index operations, it commits in phases and cannot run inside an outer transaction, so PostgreSQL raises SQLSTATE 25001 (active_sql_transaction).

  • REINDEX CONCURRENTLY issued after BEGIN.
  • Common in migration tools that wrap statements.
  • Must run standalone with autocommit.

What the server log shows

ERROR:  REINDEX CONCURRENTLY cannot run inside a transaction block

Why PostgreSQL raises this — what the manual says

the REINDEX reference (Notes):

“Another difference is that a regular REINDEX TABLE or REINDEX INDEX command can be performed within a transaction block, but REINDEX CONCURRENTLY cannot.”

The concurrent rebuild commits between phases so it never holds a long lock. Running inside an outer transaction would prevent those intermediate commits, so PostgreSQL rejects it with 25001.

Common causes

  • Issuing REINDEX CONCURRENTLY after BEGIN.
  • A migration framework wrapping statements in transactions.
  • Autocommit disabled on the connection.

How to fix it

  1. Run it standalone with autocommit on.
  2. Mark the step as non-transactional in migration tools.
  3. Use plain REINDEX if a brief lock is acceptable and you must stay in a transaction.

Related & next steps

Reference: PostgreSQL 18 — REINDEX.

Was this helpful?