Every now and then you run into a bug that looks so much like one thing that your brain just locks onto it and refuses to consider anything else.
This was one of those.
WordPress auto updates were failing. Not always. Not consistently. Just enough to be annoying and suspicious.
So naturally, I blamed the infrastructure.
Because what else would you blame?
Step 1: Blame the shiny thing
The stack looked like this:
- Caddy in front
- Hardened headers (because of course)
- WordPress doing WordPress things behind it
And the failure smelled like a loopback issue:
- updates failing
- background checks acting weird
- vague “something couldn’t reach something” energy
So the working theory became:
Ah yes, I have finally broken WordPress with my security headers and modern HTTP stack.
Reasonable conclusion. Wrong conclusion.
Step 2: Consider switching web servers like a rational person who has lost patience
At this point I was mentally halfway through migrating to NGINX.
You know the drill:
- maybe it’s how requests are proxied
- maybe it’s some header nuance
- maybe WordPress just prefers suffering
Except there was one problem.
Core auto updates worked. Perfectly.
No errors. No complaints. Just… working.
Which is the exact moment your brain goes:
Wait. That makes absolutely no sense.
Step 3: The part where WordPress reminds you it has multiple personalities
Here’s the thing people forget, even if they’ve been around WordPress forever:
“Updates” are not one thing.
There are at least two very different paths:
- Background/core updates
- No loopback
- Just goes out to the internet, downloads stuff, writes files
- Happy path
- Loopback-based operations
- Self-HTTP requests
- Health checks
- Plugin/theme updates
- Uses internal endpoints
And those loopback requests include a little gem called:
wp_scrape_key
You probably haven’t thought about it. Neither had I.
That was a mistake.
Step 4: Blame the wrong layer for several hours
At this point the system is behaving like this:
- Core updates: fine
- Plugin updates: broken
- Site health: weird
- Proxy: looking suspicious but not provably guilty
Which leads to:
- checking headers
- checking TLS
- checking proxy configs
- staring at logs that say nothing useful
Meanwhile, the real issue is sitting there quietly in the WordPress admin UI.
Step 5: The actual culprit
The problem was not Caddy.
The problem was not headers.
The problem was:
WP Super Cache
Specifically, it was mishandling requests containing:
wp_scrape_key=
Which WordPress uses for loopback operations.
And WP Super Cache, doing exactly what it thinks is helpful, interferes with that request unless you tell it not to.
The fix (the entire fix)
Go to:
WP Super Cache → Advanced → Rejected URL Strings
Add:
wp_scrape_key=
That’s it.
No proxy changes.
No header changes.
No migrations to another web server.
No existential crisis.
Why this is such an annoying bug
Because it has all the qualities of a perfect time sink:
- It looks like an infrastructure issue
- It’s partially broken, not fully broken
- The working parts give you false confidence
- The failing parts point at the wrong layer
- The actual fix is buried in a plugin setting nobody thinks about
The almost-migration that didn’t need to happen
The best part?
I was about to move everything to NGINX over this.
Which would have changed absolutely nothing.
The bug would still be there.
Just with different config files to stare at.
Meanwhile, Caddy was sitting there doing exactly what it’s supposed to do: clean proxying, automatic TLS, modern HTTP support, zero drama.
The only drama was elsewhere.
The takeaway
If WordPress auto updates are failing and:
- core updates work
- plugin/theme updates fail
- loopback tests are unhappy
- everything “looks like” a proxy issue
Check WP Super Cache before you touch anything else.
Specifically:
wp_scrape_key=
Add it. Move on with your life.
Closing thought
This is one of those bugs that feels complicated until it suddenly isn’t.
Which is great.
Because the alternative was me rewriting a perfectly good web stack over a plugin setting.
And that would have been very on-brand for the internet.