401 Unauthorized

Client Error - Authentication required

HTTP 401 Unauthorized

What It Means

The HTTP 401 Unauthorized status code indicates that the request lacks valid authentication credentials. The client must authenticate to get the requested response. Despite the name "Unauthorized," this is about authentication, not authorization.

401 vs 403: The Key Difference

  • 401: "Who are you?" — No valid credentials provided
  • 403: "I know who you are, but no." — Authenticated but not authorized

Common Causes

  • Missing Authorization header: No token/credentials sent
  • Expired token: JWT or session token has expired
  • Invalid credentials: Wrong API key or password
  • Malformed token: Token format is incorrect
  • Revoked token: User logged out or token blacklisted

WWW-Authenticate Header

The 401 response must include a WWW-Authenticate header indicating how to authenticate:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
Content-Type: application/json

{
  "error": "unauthorized",
  "message": "Invalid or expired token"
}

Common Authentication Schemes

Scheme Header Example
Bearer Authorization: Bearer eyJhbG...
Basic Authorization: Basic dXNlcjpwYXNz
API Key X-API-Key: abc123...

How to Debug

# Check if token is being sent
curl -v https://api.example.com/users \
  -H "Authorization: Bearer your-token-here"

# Decode JWT to check expiration
echo "eyJhbGciOiJIUzI1..." | cut -d'.' -f2 | base64 -d

# Test with fresh token
curl -X POST https://api.example.com/auth/login \
  -d '{"email": "[email protected]", "password": "..."}' \
  -H "Content-Type: application/json"

Client-Side Handling

async function fetchWithAuth(url) {
  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${getToken()}`
    }
  });

  if (response.status === 401) {
    // Token expired - refresh or redirect to login
    await refreshToken();
    return fetchWithAuth(url); // Retry
  }

  return response;
}

Best Practices

  • Always include WWW-Authenticate header in 401 responses
  • Don't reveal if a user exists (use same error for invalid user/password)
  • Implement token refresh for better UX
  • Use 401 for missing/invalid auth, 403 for insufficient permissions

Frequently Asked Questions

What does HTTP 401 Unauthorized mean?
HTTP 401 Unauthorized indicates the request lacks valid authentication credentials. Despite its name, 401 is about authentication (proving identity), not authorization (having permission). The client must provide valid credentials to access the resource.
What is the difference between 401 and 403?
401 means 'I don't know who you are' -- no valid credentials were provided. 403 means 'I know who you are, but you don't have permission.' Use 401 for missing or invalid authentication, and 403 when the user is authenticated but lacks the required permissions.
Must a 401 response include a WWW-Authenticate header?
Yes. According to the HTTP specification, a 401 response must include a WWW-Authenticate header that indicates the authentication scheme the server expects, such as 'Bearer', 'Basic', or 'Digest'. This tells the client how to authenticate.
How do I debug 401 errors?
Check that the Authorization header is being sent correctly, verify the token or API key has not expired, ensure the token format matches what the server expects (Bearer vs Basic), decode JWT tokens to check the expiration claim, and test with a fresh token from your auth endpoint.
How do I monitor authenticated endpoints?
UptimeSignal supports monitoring authenticated endpoints by allowing you to configure custom headers including Authorization tokens. This lets you verify that your authenticated API endpoints are responding correctly to valid credentials.

Monitor your auth endpoints

Get alerted when auth endpoints fail with UptimeSignal.

Start monitoring free →

Related Status Codes

More Resources