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.
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
GET /admin/users HTTP/1.1
Host: app.example.com
Authorization: Bearer sk_live_example
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.