{ }HttpStatus.com

403 Forbidden

The server understood the request and identified the client but refuses to authorize access to the resource.

Defined in RFC 9110 §15.5.4

What 403 means

403 Forbidden means the server understood the request and, in most cases, knows exactly who the client is, but refuses to authorize the requested action on this resource. RFC 9110 explicitly distinguishes it from 401: a 403 does not invite the client to re-authenticate, because repeating the request with different credentials would not help, access has been actively denied. Servers may optionally hide the fact that a resource exists by returning 404 instead of 403, but 403 is preferred when confirming existence poses no security risk.

The most common cause is straightforward permissions: role-based access control denies a user's role from performing an action, an object-level ownership check fails, or an IP address falls outside an allowlist. On the filesystem side, misconfigured directory or file permissions, a web server process lacking read access to a static file, or SELinux and AppArmor policies blocking access, produce 403s that have nothing to do with application-level logic at all. These are diagnosed differently: one is a data or policy problem in the app, the other is an operating-system permissions problem on the host.

A large share of confusing 403s are actually CORS failures misread as 403. When a cross-origin request's preflight fails or the response is missing Access-Control-Allow-Origin, browsers block the response from reaching JavaScript and report a generic network or CORS error in the console, which developers sometimes describe as "getting a 403" even though the server may have returned 200 and the browser, not the server, did the blocking. The real fix in that case is CORS header configuration, not permissions, and checking the actual response in the Network tab clarifies which situation you're in.

WAFs and CDN edge security, such as Cloudflare, AWS WAF, and Akamai, generate a large volume of 403s independent of application logic: bot-detection heuristics, missing or suspicious User-Agent headers, geographic blocking, or rate-based rules can all reject a legitimate request before it reaches the origin server. Separately, static file servers with directory listing disabled return 403 for a directory URL with no index file present, rather than showing its contents, a deliberate security default, not a bug, that trips up developers expecting an automatic file listing during local testing.

Common causes

  • The authenticated user's role or permissions do not include the requested action.
  • The client's IP address is outside an allowlist or matches a blocklist rule.
  • A WAF or CDN, such as Cloudflare or AWS WAF, flagged the request as suspicious based on bot signals, headers, or rate patterns.
  • File or directory permissions on the server deny read access to the process serving the request.
  • Directory listing is disabled and no index file exists for the requested directory.
  • A CORS preflight or missing Access-Control-Allow-Origin header is being misdiagnosed as a 403 when the browser, not the server, blocked the response.

How to fix a 403

If you are the client (browser user or API caller)

  • Confirm the authenticated account actually has the role or permission the action requires.
  • Check the response headers and body for a CDN ray ID or WAF block page indicating edge-level filtering rather than an application decision.
  • Open the browser's Network tab to check the real HTTP status and headers before assuming a CORS error is a 403.
  • Verify the API key or token has the correct scope for the resource.
  • Contact the resource owner or administrator to request explicit access if permissions genuinely need to change.

If you run the server

  • Return a response body that names which permission or policy caused the denial, without leaking sensitive detail.
  • Review WAF and CDN firewall rules for false positives that block legitimate traffic, especially around User-Agent and rate-limit heuristics.
  • Fix file and directory permissions, via chmod, ACLs, or cloud IAM policies, so the serving process can read what it needs.
  • Set an explicit directory listing policy, or provide an index file, instead of leaving autoindex in its default-off state unexplained.
  • Configure CORS headers, Access-Control-Allow-Origin, -Methods, and -Headers, correctly instead of relying on a blanket 403 that also blocks legitimate origins.

Example

GET /admin/settings HTTP/1.1
Host: app.example.com
Authorization: Bearer <token>

HTTP/1.1 403 Forbidden
Content-Type: application/json
CF-RAY: 8a1f2b3c4d5e6f7g-SJC

{"error": "insufficient_permissions", "message": "Role 'viewer' cannot access /admin/settings"}
A CF-RAY header in the response is a hint that Cloudflare's edge, not the origin app, may be involved in the decision.

Try it live

Our free status responder returns a real HTTP 403 you can point tests, monitors or a browser at.

GET https://mcp.httpstatus.com/status/403

Related status codes

Tools for debugging this