Skip to main content
403

Forbidden

Active
RFC 9110 §15.5.4Since 1996APIs, file servers, admin panels

HTTP 403 Forbidden indicates the server understood the request but refuses to fulfill it. Defined in RFC 9110 §15.5.4. The client does not have permission to access this resource, and re-authenticating will not help.

Description

The 403 Forbidden status code indicates that the server understood the request but refuses to fulfill it. Providing different or additional authentication credentials will not help – the server is refusing on policy grounds, not credential failure.

The critical distinction: 401 means the request lacks valid authentication (prove who you are). 403 means the server knows who you are but your identity does not grant access to this resource. Re-authenticating will not change the outcome.

Unlike 401, there is no required response header. The server may include a body explaining why access was denied, but for security-sensitive resources it may be preferable to remain silent.

Examples

Request to restricted resource
http
DELETE /api/users/1 HTTP/1.1
Host: api.example.com
Authorization: Bearer user-token-123
403 response
http
HTTP/1.1 403 Forbidden
Content-Type: application/json

{"error": "forbidden", "message": "Only administrators can delete user accounts"}

Edge Cases

  • Wrong role or permission: user is authenticated but their account lacks the required permission. Log which specific permission check failed, not just the endpoint – makes alerts actionable.
  • IP allowlist rejection: the request came from an IP not on the approved list. Common in internal APIs, admin panels, and webhook receivers. Check your allowlist includes all relevant IPs (including load balancer IPs).
  • CSRF token validation failure often returns 403. Check that CSRF middleware is not blocking legitimate same-site requests from mobile apps or API clients that use Authorization headers instead of cookies.
  • File/directory permissions on static servers (Apache, Nginx): 403 means the filesystem denies read access. Check 'ls -la' on the target path and ensure the web server user has read permission.
  • Cloudflare WAF block: Cloudflare rules may match legitimate requests. Check the Cloudflare Firewall Events dashboard for the CF-Ray ID and the rule that triggered.
  • Security decision: some APIs return 404 instead of 403 for protected resources to prevent enumeration attacks (an attacker cannot distinguish 'does not exist' from 'exists but forbidden'). Pick one approach and document it.

When You'll See This

  • User tries to access admin-only resources
  • API key lacks required scope
  • IP address is blocked
  • File system permissions prevent access

Implementation References

LanguageConstant
Gohttp.StatusForbidden
Rusthttp::StatusCode::FORBIDDEN
Pythonhttp.HTTPStatus.FORBIDDEN
Node.jshttp.STATUS_CODES[403]
.NETHttpStatusCode.Forbidden
JavaHttpURLConnection.HTTP_FORBIDDEN

History

Present since HTTP/1.0 (RFC 1945, 1996). The confusion between 401 and 403 has been a source of developer errors since the beginning.

Related Status Codes

Related Headers

FAQ

What is the difference between 401 and 403?

401 means not authenticated (provide credentials). 403 means authenticated but not authorized (you don't have permission).

Should I return 403 or 404 for sensitive resources?

Use 404 if revealing existence is a security concern. Use 403 if the user should know it exists but lacks permission.