Skip to content

Why are custom headers missing in "304 (Not Modified)" responses?

Erica Pisani
Erica Pisani
2 min read

304 (Not Modified) responses minimize the amount of information that needs to be transferred in subsequent requests made after an initial 200 (OK) response if the resources being requested are unchanged1.

This has performance benefits for a website, particularly where larger assets such as images are involved.

If you are developing a website that makes use of custom headers in responses, it’s worth noting a behaviour with respect to headers that 304 responses have that differ from 200 responses.

If a visitor to the website were to inspect their network requests and look at a 200 response, they can expect to see not only custom headers defined for the response, but the following headers which relate to the caching of the resource2:

  • Cache-Control
  • Content-Location
  • Date
  • ETag
  • Expires
  • Vary

In a 304 response however, the specification details that1:

… a sender SHOULD NOT generate representation metadata…unless said metadata exists for the purpose of guiding cache updates.

This means that that same request, if the resources are cached on the browser, will receive a response that will generally be missing the additional metadata (in this case the custom headers) since they don’t tend to serve ‘the purpose of guiding cache updates’.

As an example to illustrate this behaviour, let’s use a demo site that Netlify has for the Next.js framework. The specific page that we’re interested in can be found here.

Looking at the ‘Network’ tab within the browser console, the request fetching the image on the page is the one that we’ll take a closer look at. It should look something like:

GET https://netlify-plugin-nextjs-demo.netlify.app/_ipx/w_3840,q_75/%2F_next%2Fstatic%2Fmedia%2Funsplash.9a14a3b9.jpg?url=%2F_next%2Fstatic%2Fmedia%2Funsplash.9a14a3b9.jpg&w=3840&q=75

and the 200 response headers:

HTTP/2 200 OK
age: 0
cache-control: public, max-age=0, must-revalidate
content-type: image/jpeg
date: Tue, 23 Aug 2022 01:05:36 GMT
etag: "3b-XMihzCU33fI+mTMhk6V4yc9TZww"
server: Netlify
strict-transport-security: max-age=31536000
x-nf-request-id: 01GB43QGZ949EAFF6HBMX480RG
x-test: foobar
X-Firefox-Spdy: h2

Now if we were to refresh the page, we’ll see a 304 response for that request instead:

HTTP/2 304 Not Modified
cache-control: public, max-age=0, must-revalidate
date: Tue, 23 Aug 2022 01:08:03 GMT
etag: "3b-XMihzCU33fI+mTMhk6V4yc9TZww"
server: Netlify
x-nf-request-id: 01GB43W0VGYVR87CHSMZ70T4HQ
X-Firefox-Spdy: h2

Notice how the x-test custom header near the bottom of the list for the 200 response is now missing from the 304 response.

Wrap up

I hadn’t realized until recently that the minimization of data in a 304 response extended to the response headers, and so for those who have run into this behaviour and were also a bit puzzled as to why this happens, I hope this quick explanation was helpful.

Happy coding!


📫
Enjoy this post? Subscribe to be notified when I publish new content!
web development

Comments


Related Posts

Members Public

How to change the version of an npm package associated with a specific tag

If publishing experimental npm packages is a somewhat regular part of your development workflow, you've likely experienced some nerves around publishing that package incorrectly such that it becomes the version that anyone newly installing or upgrading the package gets. If you find that you accidentally did exactly this

How to change the version of an npm package associated with a specific tag
Members Public

Edge Side Includes

A popular use case for edge computing among web and full stack developers is the injection of dynamic content into static assets and pages. This technique increases the performance of our applications by allowing us to cache more of our content at the edge or at the Content Delivery Network

Members Public

Omitting CSS Rules Using the :not Pseudo-class

With the proliferation of design libraries in order to reduce bugs within the UI, create a more consistent user experience, and increase developer velocity in order to get features shipped faster, it’s common to have CSS stylesheets that are more generic in nature. However, like most things, there are