error http

HTTP 401 Unauthorized

Understanding HTTP 401 Unauthorized - the request requires authentication. The client must provide valid credentials to access the resource.

What It Means

HTTP 401 Unauthorized indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. The server must include a WWW-Authenticate header indicating the authentication scheme to use.

Despite the name “Unauthorized,” this status code is about authentication (proving identity), not authorization (having permission). If you’re authenticated but lack permission, 403 Forbidden is the correct response.

Common Causes

  • Missing authentication token or API key
  • Expired JWT or session token
  • Invalid or corrupted credentials
  • Incorrect API key or secret
  • Token not included in the correct header format
  • Session has timed out
  • OAuth access token has been revoked

How to Fix

Check your authentication header

# Bearer token authentication
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/protected

# Basic authentication
curl -u username:password https://api.example.com/protected

# API key in header
curl -H "X-API-Key: YOUR_API_KEY" https://api.example.com/protected

JavaScript / Fetch

// Ensure the Authorization header is set correctly
const response = await fetch('/api/protected', {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  }
});

if (response.status === 401) {
  // Token may be expired — attempt to refresh
  const newToken = await refreshAccessToken();
  const retryResponse = await fetch('/api/protected', {
    headers: {
      'Authorization': `Bearer ${newToken}`,
      'Content-Type': 'application/json'
    }
  });
}

Axios interceptor for automatic token refresh

axios.interceptors.response.use(
  response => response,
  async error => {
    if (error.response?.status === 401 && !error.config._retry) {
      error.config._retry = true;
      const newToken = await refreshAccessToken();
      error.config.headers['Authorization'] = `Bearer ${newToken}`;
      return axios(error.config);
    }
    return Promise.reject(error);
  }
);

Server-side middleware (Express.js)

const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (!token) {
    return res.status(401).json({
      error: 'Authentication required',
      message: 'Please provide a valid Bearer token'
    });
  }

  try {
    const user = jwt.verify(token, process.env.JWT_SECRET);
    req.user = user;
    next();
  } catch (err) {
    return res.status(401).json({
      error: 'Invalid token',
      message: 'Token is expired or malformed'
    });
  }
};
  • HTTP 403 - Forbidden: You are authenticated but do not have permission to access this resource.
  • HTTP 400 - Bad Request: The request itself is malformed, not an authentication issue.