When Cloudflare Sneezed and WordPress Caught a Fatal Error

On June 13, Cloudflare had a bad day.

And when Cloudflare has a bad day, a surprisingly large chunk of the internet decides to lie down and rethink its life choices – **including sites that aren’t even on Cloudflare**.

This is a story about one such day, one client site, one very unhelpful array_map() call, and how a licensing check managed to take down wp-admin.


The Symptom: wp-admin Just… Dies

One of my client’s WordPress sites suddenly started throwing a fatal error in the admin:

Uncaught Error: array_map(): Argument #2 ($array) must be of type array, null given

Stack trace pointed straight into Yoast SEO:

wordpress-seo/inc/class-addon-manager.php on line 820

At this point, WordPress was completely inaccessible. No dashboard, no plugins page, nothing. Just vibes and a stack trace.

Disabling Yoast instantly fixed the issue.

That’s usually your first clue that this is about to get interesting.


The Plot Twist: The Site Wasn’t Even on Cloudflare

Here’s where it gets fun:

  • The client site was not using Cloudflare
  • The same setup had worked fine earlier

If you’ve ever debugged WordPress long enough, you know what this smells like:

“Something external returned garbage, and nobody checked it.”


The Root Cause: A Broken License Check

Digging into Yoast’s code revealed the real culprit.

Yoast makes a request to:

https://my.yoast.com/api/sites/current

During the Cloudflare outage, this endpoint started returning:

{
  "statusCode": 404,
  "error": "Not Found",
  "message": "No sites found"
}

Important detail:
This response was still treated as valid by the plugin.

Even worse – Yoast caches this response.

So once your environment got poisoned by this response, congratulations 🎉
Every Yoast-enabled WordPress site on your machine is now broken until that cache clears.


Where Things Actually Blew Up

Here’s the exact line that caused the fatal error:

'subscriptions' => array_map(
    [ $this, 'map_subscription' ],
    $site_information->subscriptions
),

The assumption here is bold and optimistic:

“Surely $site_information->subscriptions is always an array.”

Except… it wasn’t.

It was null.

And PHP, understandably, does not appreciate being lied to.


But Wait – There’s More (HTTP Status Codes 🤡)

While investigating, another questionable bit of logic surfaced:

if ( $response_code === 200 || strpos( $response_code, '200' ) !== false ) {

Cloudflare uses its own 1200-range HTTP status codes.

So yes – in theory – a 1200 could pass a “contains 200” check.

To be clear: this wasn’t the root cause this time.
But checking status codes this way is… let’s call it “optimistic programming.”


Why This Affected Sites Not on Cloudflare

Because Cloudflare wasn’t breaking your site.

It was breaking Yoast’s licensing API, which:

  • Sits behind Cloudflare
  • Is required for Yoast Premium validation
  • Is called during admin_init

So even if your site never touched Cloudflare:

  • Yoast did
  • The response was malformed
  • The plugin didn’t validate it
  • wp-admin paid the price

Classic supply-chain failure.


The Fix: Be Less Trusting

I raised a PR with Yoast to make this logic more defensive:

🔗 PR: https://github.com/Yoast/wordpress-seo/pull/22353

What the fix does

  • Verifies that:
    • url exists
    • subscriptions exists
    • subscriptions is actually an array
  • Falls back to safe defaults if the API response is incomplete
  • Prevents fatal errors in wp-admin due to external outages

The key change

$response = $api_request->get_response();

if ( isset( $response->url, $response->subscriptions ) && is_array( $response->subscriptions ) ) {
    return $response;
}

return $this->get_site_information_default();

In other words:

“Trust the API, but verify – and don’t take wp-admin down with you.”


The Lesson (Again)

A few takeaways, none of them new, all of them still ignored too often:

  1. External APIs will fail
  2. CDNs will lie to you
  3. License checks should never fatal a CMS
  4. array_map() is not a validation strategy
  5. WP should degrade gracefully, not combust

Cloudflare going down is inevitable.
Your plugin taking WordPress down with it is not.


Final Thoughts

This wasn’t a WordPress bug.
This wasn’t even really a Cloudflare bug.

This was a classic case of assuming the happy path forever.

Hopefully, this fix makes Yoast a little more resilient the next time the internet sneezes.

Because it will.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *