# 42501 — insufficient_privilege

> PostgreSQL SQLSTATE 42501: insufficient_privilege, source-backed diagnosis and recovery guidance.
---

# 42501

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

SQLSTATE `42501` is **insufficient_privilege** in Class `42`. `42501` is insufficient privilege. The selected natural path calls `nextval` on a runner-owned sequence from a separate role that has schema USAGE but no sequence USAGE; PostgreSQL reports `permission denied for sequence %s`.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `42501` |
| Condition | `insufficient_privilege` |
| 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_INSUFFICIENT_PRIVILEGE` |
| Aliases | `—` |

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

## Meaning {#meaning}

`42501` is insufficient privilege. In the selected path, `nextval` reaches `nextval_internal`, which checks sequence access for the effective `GetUserId()` before advancing the sequence. Schema `USAGE` lets the restricted role resolve objects in the schema; it does not grant the sequence privilege needed by this call. The server therefore emits the `ERROR` primary `permission denied for sequence %s`, with the sequence name supplied dynamically.

The ownership boundary matters: an owner or administrative connection prepares the disposable schema and sequence, while a separate restricted role runs `nextval`. The successful repair is a narrow `GRANT USAGE ON SEQUENCE ...` made by the owner/admin connection, followed by `nextval` again as the same restricted role; it is not evidence that the restricted role may grant itself access.

The same SQLSTATE also covers other privilege boundaries. The generic ACL checker can report `permission denied for relation %s`, `permission denied for schema %s`, or a column-specific form, while owner-only operations use `must be owner of relation %s` or the corresponding object kind. Row-level security is a separate executor check: a table ACL can pass while an `INSERT` or `UPDATE` row violates a policy and raises a `new row violates row-level security policy ...` error. These are source-confirmed producer branches, not additional observations from the selected sequence run.

## Diagnosis {#diagnosis}

Check `current_user` and `session_user`, any `SET ROLE`, the database, schema, exact relation or column, and the relevant ACL. Keep the setup/grant connection separate from the probe connection: replace `runner_host`, `runner_port`, `runner_db`, and `runner_user` with the real disposable target and owner/admin credential, then connect separately as the generated restricted role (for example, `syntax_role`). A pool can otherwise make an ACL change appear to affect a different backend. If the primary names a relation, schema, or column, inspect that object's privilege rather than assuming sequence `USAGE`; `must be owner` requires checking the object's owner and effective role; an RLS primary requires inspecting the policy's `USING`/`WITH CHECK` path and the role it applies to. The error is an `ERROR` on the selected autocommit probe, so that same probe session remains `IDLE`; an explicit transaction would need its normal error-state handling before more work. Distinguish this object-privilege failure from 28000 startup authorization and 0A000 unsupported features.

## Response {#response}

Have the owner/admin connection grant only the required privilege on the exact object (the selected case needs sequence `USAGE`), or use the intended owner/security-definer or RLS policy when that is the application design. Re-run `nextval` on the same restricted-role session after the ACL change and verify the returned value and session state. A superuser would bypass ACL checks, but do not raise a role to superuser as a substitute for targeted least-privilege grants; schema `USAGE`, table privileges, and sequence privileges are separate checks. For an owner-only failure, use the owning/migration role or change ownership deliberately rather than treating an ACL grant as an owner transfer. Inspect the effective role if membership or `SET ROLE` is involved.

## Messages {#messages}

The selected sequence source path raises an explicit `ERROR` with SQLSTATE `42501` and primary `permission denied for sequence %s`. `%s` is the resolved sequence relation name; this path has no DETAIL or HINT. Other fixed ACL branches use `permission denied for relation %s`, `permission denied for schema %s`, and `permission denied for column "%s" of relation "%s"`; owner-only checks use `must be owner of relation %s` or the matching object kind. RLS `WITH CHECK` branches use `new row violates row-level security policy ...` primaries. A client exception without the server SQLSTATE and the primary for the specific branch is not sufficient to identify that `42501` producer.

## Representative case {#case}

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

The page uses the same statements as the runner registry. The owner/admin connection creates the sequence and grants schema `USAGE`; the restricted-role connection runs both `nextval` probes. Generated names such as `syntax_schema` and `syntax_role` are replaced by disposable runner values when executed, and connection placeholders such as `runner_host`, `runner_port`, `runner_db`, and `runner_user` must be replaced with the actual target rather than copied literally.

```sql
CREATE SEQUENCE syntax_schema.syntax_sequence START WITH 1;
GRANT USAGE ON SCHEMA syntax_schema TO syntax_role;
SELECT nextval('syntax_schema.syntax_sequence');
GRANT USAGE ON SEQUENCE syntax_schema.syntax_sequence TO syntax_role;
SELECT nextval('syntax_schema.syntax_sequence');
```

<!-- END SQLSTATE SNIPPET -->

The selected 18.6 run reports the structured diagnostic and passes the repair assertions; the 10.21 run passes the same case-specific checks. The downloadable case and evidence projections are [`42501 case JSON`](../data/cases/42501.json) and [`authored evidence`](../data/evidence/42501.json). The runner manifest is `verify/cases/42501/cases.json`, and the page SQL is checked against its shared registry.

## Versions {#versions}

The selected natural runtime scope is PostgreSQL 18.6 and 10.21; it does not infer behavior for every intermediate release.

## Related {#related}

- [`28000` — related condition](../28000/)
- [`0A000` — related condition](../0a000/)
- [`42601` — syntax_error](../42601/)

## Sources {#sources}

- `src.errcodes.18.6` — fixed `errcodes.txt` definition at commit `724edf9bde9d356724ad384a2e196edc3c9f80f7`; SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt)).
- `src.sequence-permission.18.6` — `src/backend/commands/sequence.c` at `REL_18_6` commit `724edf9bde9d356724ad384a2e196edc3c9f80f7`; fixed blob SHA-256 `3e5afe17d5a84862fae502a5481211220368f1d639e9d07ba6f96ee8be92a8d8` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/sequence.c#L652-L655)).
- `src.sequence-permission.10.23` — `src/backend/commands/sequence.c` at `REL_10_23` commit `02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4`; fixed blob SHA-256 `5510e1266e8d8c548a4318d753392e92e689d348f3353a2aa53d8dea871c44ab` ([source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/commands/sequence.c#L605-L608)).
- `src.aclcheck-errors.18.6` / `src.aclcheck-errors.10.23` — fixed `src/backend/catalog/aclchk.c` ACL-kind tables map no-privilege and not-owner results to relation/schema/column messages; blob SHA-256 `9700258318959b47c42edb423418fb511dd3a008023e732f601eecf4c80868f8` / `3a4330bd55ea8c0ec12324d7046ec31d64c920f99196235b84612d6cd1a4b26c` ([18.6 source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/aclchk.c#L2793-L2795), [10.23 source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/catalog/aclchk.c#L3301-L3449)).
- `src.rls-errors.18.6` / `src.rls-errors.10.23` — fixed `src/backend/executor/execMain.c` row-level security `WITH CHECK` errors; blob SHA-256 `33b97337fa23a649c5e7a092e1bd405a54e8503529236c62c9d5bb93a1774a8d` / `386d09f7e964ebc426a554cf51ac7cb505c67cc95b971ee7acad1a6e0a9d0c1a` ([18.6 source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/execMain.c#L2332-L2365), [10.23 source](https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/executor/execMain.c#L2188-L2208)).
- `src.calls.REL_18_6` / `src.calls.REL_10_23` — fixed call scans, SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf` / `00d16d3eb01b71ccf1b245c8f3102f9d0ec9f36fb02777b8dd1b99fcb263040c`.
