What Does HTTP 401 Unauthorized Mean?
HTTP 401 Unauthorized indicates that the request lacks valid authentication credentials for the target resource. The server is telling the client: "You need to authenticate before I can give you what you asked for."
Despite being named "Unauthorized," this status code actually means unauthenticated. The client either did not provide credentials at all, or the credentials it provided are invalid (wrong password, expired token, etc.). For permission issues where the user is authenticated but lacks access rights, the correct code is 403 Forbidden.
The 401 response must include a WWW-Authenticate header that tells the client what authentication scheme the server accepts (e.g., Basic, Bearer, Digest). This lets the client know how to authenticate on the next attempt.
Common Causes
- Missing Authorization header: The API requires a token or API key in the request headers, but the client did not include it. This happens when code paths skip the authentication middleware or when a request is accidentally sent without headers.
- Expired JWT or session token: Access tokens (JWTs, session cookies) have expiration times. Once expired, the server rejects them with 401. The client needs to refresh the token or re-authenticate.
- Wrong Authorization header format: Common mistake: sending
Authorization: abc123instead ofAuthorization: Bearer abc123. The scheme prefix (Basic, Bearer, etc.) is required. - API key revoked or rotated: If API keys were rotated (common during security incidents), the old key no longer works. Check the API provider's dashboard for your current key.
- CORS stripping the Authorization header: In browser-based requests, CORS preflight failures can cause the browser to strip the Authorization header from the actual request, resulting in a 401.
How to Fix It
For API Developers
- Validate token presence before parsing: Check if the Authorization header exists before attempting to decode it. Return a clear error message:
{"error": "No authorization token provided"}. - Include WWW-Authenticate header: Per the HTTP spec, 401 responses must include this header. Example:
WWW-Authenticate: Bearer realm="api", error="invalid_token". - Distinguish between missing and invalid tokens: "No token provided" vs "Token expired" vs "Invalid signature" helps the client fix the issue faster.
- Implement token refresh flows: Do not force users to re-login every time their access token expires. Provide a refresh token mechanism that lets clients obtain new access tokens.
For API Consumers
- Check the Authorization header format: It must be
Authorization: Bearer <token>(note the space after "Bearer"). Some APIs useAuthorization: Basic <base64>or custom schemes. - Verify the token is not expired: For JWTs, decode the payload at jwt.io and check the
expclaim. If expired, refresh or re-authenticate. - Check API key scopes: Some APIs require specific scopes. A read-only token used for a write operation may return 401 rather than 403.
- Inspect the response body: The 401 response often includes details about what went wrong. Log the full response, not just the status code.
Code Examples
401 Response from an API
Successful Authentication
Express.js Auth Middleware
Frequently Asked Questions
Authorization: Bearer <token> with the space. 3) Verify the token has not expired. 4) Ensure you are hitting the right environment (production vs staging keys). 5) Check if your IP is allowlisted if the API uses IP restrictions.WWW-Authenticate: Basic, browsers display a native username/password dialog. This is HTTP Basic Authentication. If the popup keeps appearing, your credentials are wrong. If you want to avoid the popup in your web app, use token-based auth (Bearer) instead of Basic auth, or handle 401 in JavaScript with fetch() and show a custom login form.