# 55006 — Object in use

> PostgreSQL SQLSTATE 55006: Object in use (object_in_use), source-backed diagnosis and recovery guidance.
---

# 55006 — Object in use

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

`55006` reports that the requested object operation conflicts with active use. This page selects a same-session cursor holding a table in an explicit transaction; database users, logical replication, and pending trigger-event branches are distinct.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `55006` |
| Condition | `object_in_use` |
| 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_OBJECT_IN_USE` |
| Aliases | `—` |

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

## Meaning {#meaning}

The selected table-command template is `cannot %s "%s" because it is being used by active queries in this session`. Its relation reference count covers an active portal or scan in the same backend, rather than a generic permission problem. The same table-use guard has a separate `cannot %s "%s" because it has pending trigger events` branch for AFTER-trigger work in the current transaction. Other 55006 messages identify different blockers such as users of a database or a logical replication slot.

## Diagnosis {#diagnosis}

Identify the object and the exact session or server state holding the use. In this case inspect the explicit transaction and named cursor; for pending trigger events, finish or roll back the transaction that queued them. For database or replication variants inspect `pg_stat_activity`, slots, subscriptions, and maintenance ownership before terminating anything. A cursor owned by this backend is not the same blocker as another user's backend or a logical replication slot.

## Response {#response}

Rollback the failed explicit transaction so its transaction-owned cursor and pending trigger work are released, then repeat the DDL in a deliberate maintenance boundary. For a database-user blocker, coordinate with the owning sessions; for a logical slot, resolve the subscription/slot lifecycle. Do not use `CASCADE` or terminate unrelated sessions as a generic response.

## Observed diagnostics {#messages}

The selected source group emits `ERROR` with dynamic operation and relation names. The runtime primary was `cannot DROP TABLE "cursor_drop_table" because it is being used by active queries in this session`; it entered `INERROR`, then rollback restored `IDLE`.

## Representative case {#case}

The registry creates an empty table, begins a transaction, declares and fetches a named cursor, and attempts `DROP TABLE` on that same backend. The cursor is active even without rows, so this is the same-session active-query branch. After the real 55006, the handler rolls back, drops the table again on the same connection, and verifies that the relation is gone. This selected case does not stand in for another database user, a logical replication slot, or a pending AFTER-trigger event.

<!-- BEGIN SQLSTATE SNIPPET: active_cursor_drop -->

```sql
CREATE TABLE cursor_drop_table(id integer PRIMARY KEY);
BEGIN;
DECLARE active_cursor CURSOR FOR SELECT id FROM cursor_drop_table;
FETCH active_cursor;
DROP TABLE cursor_drop_table;
ROLLBACK;
DROP TABLE cursor_drop_table;
SELECT to_regclass('cursor_drop_table_regclass')
```

<!-- END SQLSTATE SNIPPET -->

The selected PostgreSQL 18.6 and 10.21 runs passed SQLSTATE, severity, state or disconnect recovery, repair, cleanup, and isolated-target stop assertions. See [`case JSON`](../data/cases/55006.json) and [`authored evidence`](../data/evidence/55006.json).

## Versions {#versions}

The locked catalogue records 55006 from 7.4 through the listed snapshots. The active-cursor DDL case passed on 18.6 and 10.21; it does not establish behavior for database, replication, or pending-trigger branches.

## Related {#related}

- [`55000`](../55000/)
- [`55P03`](../55p03/)

## Sources {#sources}

- `src.errcodes.18.6` — `src/backend/utils/errcodes.txt` at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; blob SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L425)).
- `src.active-cursor.18.6` — `src/backend/commands/tablecmds.c` at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; blob SHA-256 `422dc8e833df4940755973c757e338295822ba3e4c7266c40669f49f96eb15a9` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/tablecmds.c#L4431-L4435)).
- `src.pending-trigger.18.6` — the same `tablecmds.c` guard checks pending AFTER-trigger events and emits `cannot %s "%s" because it has pending trigger events` at lines 4439-4444 ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/tablecmds.c#L4439-L4444)).
- `src.active-cursor.10.23` — `src/backend/commands/tablecmds.c` at `02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4`; blob SHA-256 `6de441c88496c6cf57a836898388085ec08bf69afd70d07acdafd6089b9b5f8c` ([source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/commands/tablecmds.c#L3072-L3077)).
- `src.calls.REL_18_6` / `src.calls.REL_10_23` — fixed call scans, SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf` / `00d16d3eb01b71ccf1b245c8f3102f9d0ec9f36fb02777b8dd1b99fcb263040c`.
- `manifest.55006` / `snippet-registry.55006` — hashes are recorded in `evidence/55006.json` and each selected runtime record.
