401 vs 403 Status Codes: What's the Difference?

The 401 Unauthorized and 403 Forbidden HTTP status codes are two of the most confused status codes in web development. They both mean "you can't access this" — but for very different reasons.

The short version:

  • 401 = "I don't know who you are." (Authentication problem)
  • 403 = "I know who you are, but you can't do that." (Authorization problem)

Understanding the difference matters because it changes how you handle the error — both as a developer building APIs and as a user encountering it.


401 Unauthorized: "Who Are You?"

Despite its misleading name, the 401 status code is about authentication, not authorization. It means the server doesn't know who the client is because no valid credentials were provided.

A 401 response tells the client: "You need to log in (or provide valid credentials) before I can process this request."

When a Server Returns 401

  • No authentication token or API key was included in the request
  • The provided token has expired
  • The API key is invalid or revoked
  • The session cookie is missing or expired
  • The Authorization header is malformed

How to Fix a 401 Error

  1. Log in — if you're accessing a website, your session may have expired
  2. Include your credentials — add the API key or token to the request
  3. Refresh your token — if using OAuth or JWT, request a new token
  4. Check the format — ensure the Authorization header follows the expected pattern (e.g., Bearer <token>, Basic <base64>)

401 Response Behavior

According to the HTTP specification, a 401 response must include a WWW-Authenticate header that tells the client what authentication scheme to use:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"

This header is what makes 401 different from a generic "access denied" — it actively invites the client to authenticate and try again.


403 Forbidden: "You Can't Do That"

The 403 status code means the server understood the request and knows who the client is, but refuses to authorize it. The client's identity isn't the problem — their permissions are.

A 403 response tells the client: "I know who you are, but you don't have permission to access this resource. Authenticating again won't help."

When a Server Returns 403

  • A regular user tries to access an admin-only endpoint
  • A file or directory has restrictive permissions on the server
  • IP-based access restrictions block the request
  • A Web Application Firewall (WAF) blocks the request
  • CORS policy prevents the request from a different origin
  • A user tries to modify a resource they can only read
  • Hotlink protection prevents direct access to media files

How to Fix a 403 Error

  1. Check your role/permissions — contact an admin to get access
  2. Check file permissions — on the server, ensure files are readable by the web server user
  3. Check IP restrictions — verify your IP isn't blocked
  4. Check .htaccess or server config — look for Deny from rules
  5. Check CORS settings — if calling from a browser, ensure the server allows your origin

403 Response Behavior

Unlike 401, a 403 response does not include a WWW-Authenticate header because authentication isn't the issue. The server may or may not explain why access is forbidden — sometimes the response body includes a reason, sometimes it doesn't (for security reasons, hiding the existence of a resource).


Side-by-Side Comparison

401 Unauthorized403 Forbidden
Core meaningNot authenticatedNot authorized
The question"Who are you?""Are you allowed?"
Can be fixed by logging in?YesNo
Credentials provided?No (or invalid)Yes (but insufficient)
WWW-Authenticate headerRequiredNot included
Should the client retry?Yes, with valid credentialsNo, unless permissions change
Real-world analogyShowing up without an IDShowing your ID but not being on the guest list

Practical Examples

Example 1: API Authentication

# No API key provided → 401
GET /api/users HTTP/1.1
Host: api.example.com

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

# Valid API key, but no admin access → 403
GET /api/admin/users HTTP/1.1
Host: api.example.com
Authorization: Bearer valid-user-token

HTTP/1.1 403 Forbidden

Example 2: Website Login

A user visits https://example.com/dashboard:

  • Not logged in → redirect to login page (or return 401)
  • Logged in as a regular user, trying to access admin settings → 403

Example 3: File Access

A request for https://example.com/internal/report.pdf:

  • No session cookie → 401 (need to log in first)
  • Logged in, but the file is restricted to the finance team → 403

When to Use 401 vs 403 in Your API

Use 401 When:

  • The request has no authentication credentials at all
  • The provided credentials are invalid (wrong password, expired token, bad API key)
  • The session has expired and the user needs to log in again

Use 403 When:

  • The user is authenticated but lacks permission for the specific resource
  • The user's role doesn't allow the requested action (e.g., a viewer trying to delete)
  • The resource exists but is restricted based on business rules
  • IP or geographic restrictions block access

Edge Cases

What about a resource that doesn't exist? If an authenticated user requests a resource they shouldn't know about, some APIs return 404 instead of 403 to avoid revealing that the resource exists. This is a security practice called "resource hiding."

What if credentials are optional? If an endpoint works without authentication but returns more data with it, don't return 401 for unauthenticated requests. Return 200 with the public data.

What about 401 for authorization failures? Despite the misleading name "Unauthorized," don't use 401 for authorization failures. The HTTP spec is clear: 401 is for authentication. Use 403 for "you're logged in but not allowed."


Common Mistakes

Mistake 1: Using 403 When You Mean 401

If the user just needs to log in, use 401 — it tells the client that providing credentials will solve the problem. Using 403 implies the situation is hopeless.

Mistake 2: Using 401 When You Mean 403

If the user is logged in but doesn't have permission, use 403. Returning 401 will cause the client to try re-authenticating, which won't solve the permission problem.

Mistake 3: Returning 200 with an Error Message

Some APIs return 200 OK with {"error": "unauthorized"} in the body. This forces clients to parse the response body to detect errors. Use the proper status code instead.

Mistake 4: Always Returning 403 for Security

While it's sometimes correct to use 404 to hide resources, defaulting to 403 for all access issues loses the useful distinction between "log in" (401) and "not allowed" (403).


Summary

SituationStatus Code
No credentials provided401
Invalid or expired credentials401
Valid credentials, insufficient permissions403
Valid credentials, IP blocked403
Valid credentials, resource restricted by role403
Resource shouldn't be revealed to exist404

The simplest rule: if logging in (or providing better credentials) would fix the problem, use 401. If it wouldn't, use 403.

For monitoring your API's authentication and authorization errors, Hyperping can alert you when endpoints start returning unexpected 401 or 403 responses, helping you catch misconfigured permissions or broken authentication before your users report them.