ErrLookupBackground articles › Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership

Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership

Permission denied, not authorized, and 403-class errors appear when an access-control check inside the library or service decides the authenticated caller may not perform the action on the target resource. Developers meet this family when calling admin or integration APIs without the right role (Rocket.Chat, Appwrite), hitting cloud IAM denials through a client (Vertex via litellm), calling a tool outside an allowlist (MCP configs), attempting owner-only operations, or writing to a path the process cannot touch (EACCES). This article maps the whole family: where the rejection comes from, how each library phrases it, and which fixes hold across all of them.

Distilled from 116 documented records across 18 repositories.

Background

These errors come from the authorization layer that sits behind authentication. Authentication establishes who the caller is (session user, access key, service account, signed pubkey); authorization then evaluates whether that identity may do the action on the resource. The records show the same shape everywhere: Rocket.Chat evaluates hasPermissionAsync against a role-permission matrix, Appwrite matches the caller's roles against a function's execute permission array, AFFiNE's PermissionService resolves per-doc and per-workspace rules, rustfs runs an IAM layer plus bucket policy for S3 actions over protocol sessions, airi's plugin host checks manifest-declared grants per area/action/key, and SpacetimeDB enforces per-domain ownership. When the evaluation returns false, the request fails before any business logic runs.

From the caller's side the rejection is usually final and often uninformative. The message vocabulary varies widely: HTTP 401/403 ("Unauthorized" in Appwrite, "Access to Method Forbidden", "denied; no ingress cap"), typed error codes (error-action-not-allowed, error-not-authorized, user_unauthorized, no_permission/space_access_denied), or plain untyped strings ("not-authorized", "Not allowed") that REST layers pass through without a code. Some libraries even misclassify the failure: litellm maps a Vertex 403 into BadRequestError because a string-based branch runs before the status-code branches, and anything-llm surfaces a filesystem EACCES as a bare "Internal Server Error" with the real cause only in the server log. Several implementations run the permission check before the existence check (Rocket.Chat's updateOutgoingIntegration), so an unauthorized caller cannot distinguish "not allowed" from "does not exist" — an intentional information hedge.

The family splits along what actually decides the answer. Identity-centric checks ask which roles the caller holds, sometimes scoped to a room, channel, or doc (Rocket.Chat's named permissions, AFFiNE's doc rules). Ownership checks compare the caller to the resource's creator or owner (Rocket.Chat file deletion and own-vs-any integration management; buzz's owner-only group deletion). Policy and allowlist checks match the request against configured grants — rustfs bucket-policy Allow/Deny, openhuman's allowed_tools/disallowed_tools, tailscale's ingress capability, airi's intersected module grants — where intersection and Deny statements can only narrow access. A minority are plain filesystem denials (EACCES/EROFS) wrapped by the application. Two cross-cutting traps recur: permission state can go stale (roles revoked after the client loaded its UI, airi grants persisted for an older manifest), and some systems deliberately split permanent from transient denials — rustfs's AccessDenied versus IamUnavailable — where only the transient sibling is worth retrying.

Common causes

What usually fixes it

Go deeper

Documented occurrences

…and 96 more across the corpus — use search.

Honest provenance: generated on 2026-08-19 from AI-assisted analysis of the linked records. See how records are made.