Skip to content

403 Forbidden

The server understood the request and refuses to authorize it. Authenticating again will not help.

Status

HTTP/1.1 403 Forbidden

Details

  • Category: 4xx
  • Status: Standard. Registered with IANA and defined by a current standards-track RFC.
  • Specification: RFC 9110 §15.5.4
  • Cacheable: Only with explicit cache headers
  • Response body: Allowed
  • Retry: Do not retry

403 means the server knows what you are asking for and will not do it. Unlike 401 it is not about missing credentials: either the caller is authenticated and lacks permission, or the server refuses everyone regardless of identity.

It is also the standard face of bot detection. Anti-bot systems answer suspicious traffic with 403 rather than explaining why, which is why a 403 in an automation context usually points at the IP address, the TLS fingerprint, or the header profile rather than at the URL.

Note: A 403 is frequently bot detection rather than a permission check. If the same request succeeds from a different address, the block is on the address, not on the request.

Common causes

  • The authenticated user lacks the required role, scope, or ownership of the resource.
  • An IP allowlist, geoblock, or WAF rule rejected the request.
  • Bot detection flagged the client fingerprint, header order, or request rate.
  • Filesystem permissions or a directory listing rule on a static file server.
  • A signed URL expired or its signature did not verify.

How to fix it

As the client

  • Check whether the same request succeeds from a different IP. If it does, the block is address based rather than request based.
  • Send a complete, coherent browser header set. A request with a browser User-Agent but no Accept-Language or Sec-Fetch headers stands out immediately.
  • Verify the token scopes on an API call. Valid credentials with the wrong scope produce 403, not 401.
  • Slow down. Rate-based blocking often escalates from 429 to a sticky 403 on the offending address.

As the server

  • Say why in the body when it is safe to do so. A bare 403 is one of the hardest errors to support.
  • Return 404 instead when revealing that the resource exists is itself a leak.
  • Keep WAF rules scoped. Broad user-agent bans catch legitimate integrations along with bots.

Examples

Requesting something outside your scope

A request from an authenticated caller whose token lacks the required scope:

HTTP request

GET /admin/users HTTP/1.1
Host: app.example.com
Authorization: Bearer sk_live_example

The server knows who the caller is and still refuses. Re-authenticating will not change the outcome:

HTTP response

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8

{"error":"insufficient_scope","required":"admin:read"}

Notes for proxy users

403 is the code you meet most often when a target site dislikes your IP. Datacenter ranges are widely categorized and blocked outright, while static residential ISP addresses carry consumer reputation and are treated like ordinary visitors. If a request succeeds from a home connection and returns 403 from a server, the address type is the variable to change first.

Specifications

See also