When debugging an API call or web application, receiving an HTTP 4xx client error indicates that the client request could not be fulfilled. Two of the most common responses are status 401 and status 403.

While both represent access barriers, they signal fundamentally different problems on the server.

Core distinction: identity versus permission

The distinction centers on identity versus permission:

  • HTTP 401 Unauthorized means the server did not accept the request’s authentication credentials, or no valid credentials were provided.
  • HTTP 403 Forbidden means the server understood the request but refuses to fulfill it. The reason can involve permissions or server access policy.

What a 401 response means

An HTTP 401 status indicates that the request has not been applied because it lacks valid authentication credentials for the target resource.

When a server returns 401, it typically includes a WWW-Authenticate response header specifying the authentication scheme (such as Basic, Bearer, or Digest) that the client must provide:

HTTP/1.1 401 Unauthorized
Date: Thu, 10 Sep 2026 10:00:00 GMT
WWW-Authenticate: Bearer realm="example-api", error="invalid_token"
Content-Type: application/json

{"error": "invalid_token", "message": "The access token provided has expired."}

A 401 response is actionable: supplying valid, active credentials with the subsequent request can allow it to succeed.

What a 403 response means

An HTTP 403 status indicates that the server understood the request, but refuses to authorize or fulfill it.

Unlike 401, a 403 response does not indicate that supplying different credentials will necessarily grant access:

HTTP/1.1 403 Forbidden
Date: Thu, 10 Sep 2026 10:00:00 GMT
Content-Type: application/json

{"error": "forbidden", "message": "Your account does not have administrator privileges."}

A 403 response can happen for multiple reasons:

  • An authenticated user attempts an action restricted to higher privilege roles.
  • The target resource is protected by server access policy regardless of authentication status.

Authentication vs. authorization

The naming of HTTP 401 as “Unauthorized” is a historical artifact in the HTTP specification. In modern software engineering:

  1. Authentication (AuthN) verifies identity (“Who are you?”). This corresponds to HTTP 401.
  2. Authorization (AuthZ) evaluates permissions (“What are you allowed to do?”). This corresponds to HTTP 403.

If credentials are absent or invalid, the server answers with 401. If the identity is verified but permission is denied, the server answers with 403.

How to investigate a 401 or 403 safely

When diagnosing these status codes:

  1. Inspect request headers: Confirm whether an Authorization header, session cookie, or API key header was sent.
  2. Review the response payload: Servers often include structured error details describing whether a token expired (401) or a specific role was missing (403).
  3. Check the token expiration: Verify that API tokens or session timestamps are currently valid.
  4. Never bypass security: Do not attempt to disable authentication checks, share elevated tokens, or route around server access rules.

401 and 403 are not CORS errors

HTTP 401/403 responses and CORS are separate concerns. A browser CORS policy can prevent JavaScript from reading a 401 or 403 response, while the server response itself can still indicate an authentication or access-control issue.

An HTTP 401 or 403 status code is returned directly by the origin server based on credentials or access rules. If client-side JavaScript in a browser makes a cross-origin request that encounters a 401 or 403 response, the browser will not expose the response body to client code unless valid CORS response headers (such as Access-Control-Allow-Origin) are present.

A practical comparison table

Feature HTTP 401 Unauthorized HTTP 403 Forbidden
Primary Issue Authentication failure (missing or invalid credentials) Access refusal (insufficient permissions or policy)
Challenge Header Commonly returns WWW-Authenticate Does not return challenge headers
Client Identity Unauthenticated or credentials rejected Permission denied or blocked by access policy
Retrying Identical Request Fails again until valid credentials are provided Fails again because permissions remain insufficient
Fix Location Provide valid API token, key, or session Request elevated permissions or adjust access policy

What to check before changing code

Before altering application code or authentication handlers, verify:

  1. Did the client send the expected authentication header format (e.g., Authorization: Bearer [redacted])?
  2. Has the token or session expired or been revoked?
  3. Does the authenticated user or service account have the required role or permission for the requested resource (https://api.example.test/v1/resource)?
  4. Does the server enforce a specific access policy that restricts this operation?

Key takeaway

Use HTTP 401 when authentication is required and missing or invalid. Use HTTP 403 when the server understands the request but refuses to grant access based on permissions or security policy. Neither status indicates a CORS configuration defect by itself.