Axios Handling of HTTP 304 Not Modified

When the Axios HTTP client receives an HTTP 304 Not Modified response, its behavior depends on default status validation rules and the runtime environment (browser vs. Node.js). By default, Axios treats a 304 status as an error and rejects the request promise because it only considers 2xx status codes successful. This article details why this rejection occurs, how the execution environment impacts the response, and how to properly configure Axios to handle 304 statuses.

Default Status Validation in Axios

Axios determines whether a promise should resolve or reject using the validateStatus configuration option. By default, validateStatus is defined as:

validateStatus: function (status) {
  return status >= 200 && status < 300;
}

Because an HTTP 304 code falls outside the 200–299 range, Axios creates an AxiosError and rejects the promise. If an application does not intercept or catch this error, the request fails, even though HTTP 304 is a standard response indicating that a cached version of the resource is still valid.

Environment Differences: Browser vs. Node.js

The runtime environment plays a significant role in how a 304 response is surfaced to your code:

How to Handle HTTP 304 in Axios

To prevent Axios from throwing an error upon encountering a 304 status, you can customize the validateStatus function in your request configuration or global Axios instance:

const axios = require('axios');

axios.get('https://api.example.com/data', {
  headers: {
    'If-None-Match': '"etag-value-12345"'
  },
  validateStatus: function (status) {
    return (status >= 200 && status < 300) || status === 304;
  }
})
.then(response => {
  if (response.status === 304) {
    // Resource has not changed; use application-level cached data
    console.log('Resource not modified. Using cached data.');
  } else {
    // Fresh data received
    console.log('Received fresh data:', response.data);
  }
})
.catch(error => {
  console.error('Request failed:', error);
});

Managing Cached Payloads

Accepting an HTTP 304 status via validateStatus does not automatically populate response.data. A 304 response typically contains empty response headers and no body. When working in server-side environments like Node.js, your application architecture must maintain its own local cache layer (such as Redis, an in-memory store, or an Axios caching interceptor) to serve the stored data when a 304 status is returned.