# 57014 — query_canceled

> PostgreSQL reports SQLSTATE 57014 when a running statement is canceled, including by statement_timeout. Classify the cancel source, verify transaction state, and confirm that a follow-up operation is safe.
---

## At a glance {#at-a-glance}

`57014` is PostgreSQL's `query_canceled` condition in Class 57, `operator_intervention`. It indicates that the server interrupted a statement. The same SQLSTATE covers several cancellation sources, so the primary message and server context are needed to distinguish a statement timeout, an explicit client cancel, a recovery conflict, or another administrative path.

The representative case sets `statement_timeout` to 100 ms and executes `pg_sleep(1)`. PostgreSQL returns `canceling statement due to statement timeout`; the autocommit connection remains `IDLE`, and a subsequent `SELECT 1` returns `1`. This proves the timeout path and connection usability for this case, not that every canceled command has no side effects or the same transaction state.

Run `57014-registry-final-20260909` passed on PostgreSQL 18.6 and isolated PostgreSQL 10.21. The per-target assertions and structured observations are retained in the [public evidence JSON](../data/evidence/57014.json).

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| Field | Value |
| --- | --- |
| SQLSTATE | `57014` |
| Condition | `query_canceled` |
| Status | `active` |
| Known present by | `7.4` |
| Locked snapshots | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| Macros | `ERRCODE_QUERY_CANCELED` |
| Aliases | `—` |

<!-- source facts: data/errcodes/57014.json -->
<!-- END SQLSTATE FACTS -->

## Meaning and trigger paths {#meaning}

`statement_timeout` starts a timer for each statement and asks the backend to process an interrupt when the budget expires. In the fixed source path, `ProcessInterrupts` emits `ERRCODE_QUERY_CANCELED` with `canceling statement due to statement timeout`. A client cancel uses the same SQLSTATE with `canceling statement due to user request`; lock timeout and some recovery paths use their own message or detail.

Cancellation stops the current statement at an interruptible point. It is not a general assertion that all work associated with a request has ceased, that an external side effect was undone, or that a transaction is usable without rollback. The transaction boundary, statement type, and cancellation source determine what must be cleaned up.

## Messages and diagnostics {#messages}

The representative operation is a dedicated autocommit connection with a 100 ms timeout:

<!-- BEGIN SQLSTATE SNIPPET: statement_timeout_cancel -->
```sql
SET statement_timeout = '100ms';
SELECT pg_sleep(1);
SELECT 1;
```
<!-- END SQLSTATE SNIPPET -->

PostgreSQL 18.6 returned:

```text
SQLSTATE: 57014
severity: ERROR
message_primary: canceling statement due to statement timeout
source: postgres.c / ProcessInterrupts / line 3446
```

PG10 returned the same primary message with source line 3018. There is no universal detail template for `57014`; preserve `message_detail`, `message_hint`, context, and the statement that was interrupted when present.

## Diagnosis {#diagnosis}

Record SQLSTATE, severity, primary message, detail, hint, context, backend PID, statement text, timeout settings, and the source of cancellation. Distinguish `statement_timeout` from `lock_timeout`, a client cancel, an administrator request, and a standby recovery conflict. Search server logs with the SQLSTATE and backend PID when the client diagnostic is incomplete.

Check transaction status after the error. The autocommit timeout case was `IDLE` and accepted `SELECT 1`; an error inside an explicit transaction may leave it `INERROR` and require rollback. If the interrupted statement changed rows before an error, verify the database state rather than assuming a request-level rollback outside the current transaction.

## Response and repair {#response}

Tune the operation and its budget based on the cause:

- Optimize or batch an overlong query, and set a timeout that matches the work's service-level budget.
- Handle a client or administrative cancel as a control decision, then inspect whether the application should retry.
- Resolve lock contention separately when the message identifies `lock timeout`; increasing statement timeout does not repair a lock queue.
- Roll back an aborted explicit transaction before issuing unrelated commands, and verify any external work whose lifetime is not controlled by PostgreSQL.

The representative follow-up query returned `1` with the connection `IDLE`. That is the repair assertion for this autocommit sleep case; it is not a promise that a canceled write, cursor, or transaction can always be resumed in place.

## Versions and boundaries {#versions}

The catalogue has a definition-presence observation for `57014` at PostgreSQL 7.4 and through the locked 8.4.22 pre-9.0 definitions, then in every listed formal snapshot through PostgreSQL 18.6 and the PostgreSQL 19 Beta 3 preview. This is a definition-only presence boundary, not an exact implementation introduction or runtime-use claim. No condition definition change is recorded in the scanned range.

The statement-timeout case passed on PostgreSQL 18.6 and 10.21. The SQLSTATE is shared by other cancellation mechanisms whose messages and transaction effects differ, so this evidence is limited to a server-side statement timeout on an autocommit connection.

## Related {#related}

[`40P01` — `deadlock_detected`](../40p01/) is resolved by the lock manager as a cycle, not by a timeout budget. [`53300` — `too_many_connections`](../53300/) is a startup capacity failure. [`42P01` — `undefined_table`](../42p01/) is a parse-time name error. [`25P02` — `in_failed_sql_transaction`](../25p02/) can follow a cancellation when the surrounding explicit transaction is aborted.

## Sources {#sources}

Structured evidence is recorded in the [public evidence JSON](../data/evidence/57014.json). Source records are fixed to PostgreSQL commit `724edf9bde9d356724ad384a2e196edc3c9f80f7`; runtime records retain both target IDs and structured observations.

- `src.errcodes.18.6` — [`errcodes.txt`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L432-L438)
- `src.postgres.18.6` — [`postgres.c`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L3439-L3447)
- `doc.config.18` — [Statement behavior and statement_timeout](https://www.postgresql.org/docs/18/runtime-config-client.html#GUC-STATEMENT-TIMEOUT)
- Runtime: `57014-registry-final-20260909` on latest and pg10; structured observations are in the [public evidence JSON](../data/evidence/57014.json)
