---
layout: post
title: "When Safari’s ‘Ignore Cache’ Ignored Cache-Control"
date: 2026-08-17 16:11:40
categories: Web Development
main: ""
meta: "Safari Technology Preview 250 fixed a subtle Web Inspector bug that overwrote page-authored Cache-Control request headers when the resource cache was disabled."
faq:
- question: "What did Safari Technology Preview 250 fix?"
answer: "It fixed a Web Inspector bug where disabling the resource cache replaced a page-authored Cache-Control request header with no-cache before the request reached the network."
- question: "Did the bug overwrite Cache-Control response headers?"
answer: "No. The WebKit change concerns a Cache-Control request header set by page code, not the Cache-Control response header returned by an origin or CDN."
- question: "Does Ignore Cache still bypass Safari’s local cache?"
answer: "Yes. Web Inspector still applies its internal cache-bypass policy, but it now preserves any Cache-Control request header that the page has already supplied."
- question: "How should I test warm-cache behaviour in Safari?"
answer: "Keep caching enabled, load the page normally, then reload or revisit it without clearing data. Treat Ignore Cache as a separate diagnostic condition."
---
As you know, I’m a little bit obsessed with caching. I’ve written about
[`Cache-Control`](/2019/03/cache-control-for-civilians/), [how much cache
coverage sites leave on the table](/2024/08/cache-grab-how-much-are-you-leaving-on-the-table/),
[better reuse with
`No-Vary-Search`](/2026/05/better-browser-caching-with-no-vary-search/), and even
[why we have a `Cache-Control` _request_
header](/2025/03/why-do-we-have-a-cache-control-request-header/). That is why
this otherwise rather vague line in the [Safari Technology Preview 250 release
notes](https://webkit.org/blog/18191/release-notes-for-safari-technology-preview-250/)
caught my eye:
> Fixed disabling the resource cache overwriting a `Cache-Control` header
> already set by the page.
At first glance, that almost sounds like the feature working as intended: of
course disabling cache has to override caching somehow. But disabling WebKit’s
local resource cache and replacing a header that the page deliberately added to
its request are two very different things.
The release note piqued my interest, so I dug into [the underlying WebKit
change](https://github.com/WebKit/WebKit/commit/96437189e7eecba977fe0a452b7e35fecc6ea776).
The bug is small, specific, and absolutely fascinating.
{% include promo.html %}
## Web Inspector Was Changing the Outgoing Request
Safari Web Inspector’s [Ignore
Cache](https://webkit.org/web-inspector/network-tab/#controlling-resource-caching)
toggle tells WebKit not to use cached resources for future requests while Web
Inspector is open. That is a useful development convenience, particularly when
you need to know that you’re looking at the latest copy of a resource.
Before this fix, WebKit did two things when that toggle was active:
* it set an internal policy that bypassed its resource cache; and
* it set the outgoing request’s `Cache-Control` and `Pragma` headers to
`no-cache`.
The first behaviour is exactly what we asked for. The second is where things got
interesting: WebKit _set_ those headers even if the page had already supplied
its own. The debugging setup didn’t just change whether Safari could reuse
a local response; it changed the request that the application sent.
## This Is a `Cache-Control` Request Header
We tend to think of `Cache-Control` as a response header:
```http
HTTP/2 200
Cache-Control: max-age=31536000, immutable
```
That is the origin telling browsers and other caches how they may store and
reuse its response. But, as [we’ve looked at
before](/2025/03/why-do-we-have-a-cache-control-request-header/),
`Cache-Control` can also appear on a _request_, where the client tells caches
what kind of stored response it is prepared to accept.
A page can add one itself:
```js
fetch('/data.json', {
headers: {
'Cache-Control': 'max-age=12345'
}
});
```
That is almost the exact case in WebKit’s new regression test. With caching
enabled, the server receives `max-age=12345`. With caching disabled and no
page-authored header, it receives WebKit’s `no-cache`. Crucially, with caching
disabled _and_ the page setting `max-age=12345`, the server should still receive
`max-age=12345`.
Before the fix, it received `no-cache` instead. The value that the page asked
for never reached the network.
## Cache Bypass and Request Semantics Are Now Separate
The fix is pleasingly small. When Web Inspector has disabled caching, WebKit now
adds its `no-cache` headers only if the request doesn’t already contain them. It
still applies its internal `ReloadIgnoringCacheData` policy, so the local
resource cache remains bypassed either way.
In other words:
```text
Page-authored request header: preserved
Web Inspector cache bypass: still applied
```
This is the distinction that the release note hides. Web Inspector can ignore
its local cache without rewriting the application’s request to achieve it.
This also wasn’t a general Safari caching failure. The affected condition was
much narrower: Web Inspector had disabled the resource cache, and the request
already contained a page-authored `Cache-Control` header. The release note
doesn’t establish which shipping Safari versions contained the old behaviour,
only that Safari Technology Preview 250 contains the fix.
## How This Could Trip You Up
Changing `max-age=12345` to `no-cache` is not cosmetic. A shared cache, CDN, or
origin that receives the request may respond differently because `no-cache`
requires a stored response to be successfully validated before reuse. The tool
that was meant to help inspect the request had changed the request’s caching
semantics before it reached the network.
That could lead to some wonderfully confusing investigations. Server logs might
show a `no-cache` header that the application never sent. An endpoint might
behave differently only while Web Inspector is open and Ignore
Cache is active. Or a supposed warm-cache test might make every request
look as though the user had explicitly demanded revalidation.
None of those observations would be false, exactly; they would be true only
under the debugging conditions that produced them.
For caching work, I keep the conditions separate:
* **Cold cache:** clear the relevant data once, then load with caching enabled.
* **Warm cache:** load or revisit normally with caching enabled.
* **Cache disabled:** treat this as a separate diagnostic mode, not a warm-cache
test.
It is also worth recording the browser version, whether Web Inspector was open,
and whether Ignore Cache was active. If the request headers
themselves are in question, compare what Web Inspector shows with CDN/origin
logs or another capture outside that setup.
This is a tiny browser bug with a tiny fix, not a particularly harmful caching
failure. But it is a lovely bit of trivia about how developer tools work: before
the fix included in Safari Technology Preview 250, asking Web Inspector to
ignore its own cache could also make it ignore what the page had already said
about caching.
That is exactly the kind of distinction that keeps caching interesting long
after any sensible person would have moved on.