Skip to main content
4xx Client Error

401 Unauthorized

Authentication is required and has failed or has not yet been provided.

Meaning & Description

The 401 Unauthorized status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. Despite its name, this code means "unauthenticated" rather than "unauthorized".

Common Causes

  • Missing `Authorization` header in the request
  • Expired access tokens or session cookies
  • Typo in the provided API key
  • Bearer token format is incorrect (e.g., missing the "Bearer " prefix)

How to fix a 401 error

  1. Check if the `Authorization` header is present and correctly formatted.
  2. Verify that the provided token or API key has not expired.
  3. Ensure that the client is sending cookies correctly if using cookie-based auth.
  4. Look at the `WWW-Authenticate` response header to determine the expected authentication scheme.

Browser & SEO Behaviour

Browser Behavior

If a WWW-Authenticate header with the "Basic" scheme is present, the browser will typically prompt the user with a native login dialog.

SEO Impact

Crawlers cannot access content behind a 401. If public content suddenly returns 401, it will be dropped from search indexes.

CDN Behavior

Not cached by default. Some CDNs can perform edge authentication and return 401 before the request reaches the origin.

Code Examples

Node.js (Express)
app.get('/api/protected', (req, res) => {
  const token = req.headers.authorization;
  if (!token || !verifyToken(token)) {
    res.set('WWW-Authenticate', 'Bearer');
    return res.status(401).json({ error: 'Valid authentication token required.' });
  }
  res.json({ data: 'Secret information' });
});
Python (FastAPI)
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

@app.get("/users/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
    if not is_valid(token):
        raise HTTPException(
            status_code=401,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return {"token": token}
Go (net/http)
func authMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := r.Header.Get("Authorization")
        if token == "" {
            w.Header().Set("WWW-Authenticate", `Bearer realm="api"`)
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        next.ServeHTTP(w, r)
    })
}
C# (ASP.NET Core)
[HttpGet("secure-data")]
[Authorize]
public IActionResult GetSecureData()
{
    // If [Authorize] fails, ASP.NET Core automatically returns a 401 Unauthorized
    // (or 302 redirect to login, depending on authentication setup).
    return Ok(new { Secret = "42" });
}
curl
curl -i -X GET https://api.example.com/protected \
  -H "Authorization: Bearer invalid_or_expired_token"

Raw HTTP Response Example

HTTP Response
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="The access token expired"
Content-Type: application/json
Content-Length: 53

{
  "error": "Authentication failed or token expired"
}

Real-world Examples

AWS API Gateway: Returns 401 when a requested API requires an API key but none is provided.
Twitter API: Returns 401 when OAuth 1.0a signatures are invalid or tokens are revoked.
Auth0: Standard response when a JSON Web Token (JWT) is expired or signature validation fails.

Frequently Asked Questions

What is the difference between 401 and 403?

401 means "you are not authenticated" (we don't know who you are). 403 means "you are authenticated, but you don't have permission" (we know who you are, but you can't do this).

Why is the header called WWW-Authenticate?

It is a historical artifact from the early web. The specification requires a 401 response to include at least one WWW-Authenticate challenge header to tell the client how to authenticate.

How do I resolve a 401 error in my app?

Ensure you are passing the correct credentials (like a token or cookie) in your request headers, and that those credentials have not expired.

Can I redirect to a login page instead of returning 401?

Yes, web applications often return a 302 Redirect to a login page instead of a 401 when a browser hits a protected route.

Should I return 401 for an invalid password?

Yes, 401 is the correct code when an authentication attempt fails due to invalid credentials like a bad password.

Did You Know?

The 401 status code strictly means "unauthenticated", but due to a historical naming mistake in the RFC, it is named "Unauthorized".

Without the `WWW-Authenticate` header, a 401 response technically violates the HTTP specification.

Developer Tips

  • Always include the `WWW-Authenticate` header when returning a 401 to be strictly compliant with HTTP standards.
  • Use standard authentication schemes like `Bearer` or `Basic` in the `WWW-Authenticate` header to allow automated clients to handle the error.
  • Use generic error messages like "Invalid credentials" rather than "Password incorrect" to prevent user enumeration attacks.

Interview Questions

These are questions you might face in a backend or API design interview that touch on HTTP 401.

Explain the difference between 401 Unauthorized and 403 Forbidden.

401 implies the client has not provided valid authentication (identity is unknown or invalid). 403 implies the client is authenticated, but does not have authorization or permissions to access the specific resource.

What HTTP header is required in a 401 response?

The `WWW-Authenticate` header is required by the HTTP specification. It tells the client what authentication scheme is expected.

If a user tries to access a document they do not own, should you return 401 or 403?

You should return a 403 Forbidden. The user is logged in (authenticated), but they lack the permissions to access that specific document (unauthorized).

Common Interview Mistakes

  • Saying 401 is about permissions or roles (that is 403).
  • Forgetting the role of the `WWW-Authenticate` header.
  • Confusing 401 with 407 Proxy Authentication Required.