403 Forbidden

Access denied without any path to authenticate is communicated through the 403 Forbidden status code. The server refuses the request and offers no Authentication scheme to gain access.

Usage

When a 403 Forbidden error arrives, the client does not have sufficient permissions to access the resource. This is a common and general error telling the client the request is not allowed. This status differs from 401 Unauthorized because the error persists even after the client re-authenticates and re-submits the request. The more specific 405 Method Not Allowed status indicates the resource is available but the specific HTTP method is not permitted.

403 vs 401

403 Forbidden answers a request the server understands and refuses on permission grounds, while 401 answers a request arriving without a usable identity. The distinction rests on whether different credentials change anything. A 403 stands for the requester whatever credential the requester supplies, so the server offers no Authentication challenge and the client gains nothing by retrying with a new token.

401 responses carry a WWW-Authenticate header naming an accepted scheme. 403 responses carry no such header, and adding one contradicts the meaning of the status.

The terminology runs against intuition. 403 Forbidden is the authorization outcome, covering permission, and 401 Unauthorized is the authentication outcome, covering identity. The word "unauthorized" sitting on the identity code accounts for most of the confusion between the two.

Typical 403 conditions include a signed-in user reaching an admin-only path, an API key on a plan lacking the feature, a request blocked by an IP or region rule, and a WAF decision. In each, no credential the requester holds changes the outcome, which is what separates them from the 401 cases.

Serving 403 where 401 applies conceals a working path to access, leaving clients with a permanent refusal for a recoverable condition.

Example

The client requests a protected resource and the server responds with 403 Forbidden to indicate the client lacks access. The response body explains the restriction.

Request

GET /tech-news/confidential.pdf HTTP/1.1
Host: www.example.re

Response

HTTP/1.1 403 Forbidden
Content-Type: text/html
Content-Length: 150

<html>
  <head>
    <title>Access Denied</title>
  </head>
  <body>
    <p>Permission to access this resource is
    restricted.</p>
  </body>
</html>

How to fix

A 403 Forbidden means the server understood the request but refuses to authorize the action.

  1. Verify file and directory permissions on the server. On Linux, check ownership and permission bits with ls -la. The web server process (typically running as www-data or nginx) needs read access to the requested file. Standard permissions: 755 for directories, 644 for files. Fix recursively:

    find /var/www/html -type d -exec chmod 755 {} \;
    find /var/www/html -type f -exec chmod 644 {} \;
    chown -R www-data:www-data /var/www/html
    

    nginx also requires execute permission on every parent directory in the path from / to the served file.

  2. Check .htaccess or server configuration for deny rules. Apache Require directives, nginx deny rules, or similar access controls block specific paths or IP ranges. In Apache, look for Require all denied or Deny from all in .htaccess or <Directory> blocks. In nginx, look for deny all; inside location blocks. Review the relevant configuration files and check the error log for the specific deny reason.

  3. Confirm the request IP is not blocked. A firewall, web application firewall (WAF), or geo-blocking rule rejects requests from restricted addresses. Check the server's access logs for deny entries. Cloudflare, AWS WAF, and mod_security all produce 403 responses when rules trigger. Review the WAF dashboard or audit log to identify the blocking rule.

  4. Ensure the authenticated user has the required role or scope. Even with valid Authentication, the account needs the correct permission level. Verify role assignments in the application's access control system. API endpoints frequently return 403 when the token lacks required OAuth scopes.

  5. Check directory index settings when requesting a folder. Requesting a directory without a default index file (e.g., index.html) returns 403 when directory listing is disabled. Add an index file or enable listing. In nginx:

    location /files/ {
        autoindex on;
    }
    

    In Apache, add Options +Indexes to the directory configuration. Enabling directory listing on production servers poses a security risk.

  6. Check SELinux or AppArmor policies. On RHEL/CentOS systems, SELinux denies web server access to files outside expected paths even when Unix permissions allow the read. Run sestatus to check the SELinux mode and review /var/log/audit/audit.log for denied entries. Relabel files with restorecon -Rv /var/www/html or set the correct context with chcon.

  7. Inspect SSL/TLS client certificate requirements. Servers configured for mutual TLS return 403 when the client does not present a valid certificate. Check the nginx ssl_verify_client directive or the Apache SSLVerifyClient directive.

Code references

.NET

HttpStatusCode.Forbidden

Rust

http::StatusCode::FORBIDDEN

Rails

:forbidden

Go

http.StatusForbidden

Symfony

Response::HTTP_FORBIDDEN

Python3.5+

http.HTTPStatus.FORBIDDEN

Java

java.net.HttpURLConnection.HTTP_FORBIDDEN

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_FORBIDDEN

Angular

@angular/common/http/HttpStatusCode.Forbidden

See also

Last updated: August 17, 2026