Summary

  • Cloudflare resolved incident 238b69fw6l55 at 07:12:40 UTC on 4 August after a Workers runtime release exposed an unintended global Temporal entity.
  • Temporal.Now reported 1 January 1970, while Date and Date.now() continued to report the correct time.
  • Workers that installed a Temporal polyfill only when no native implementation was present could silently skip the polyfill and calculate tokens, TTLs or date arithmetic against 1970.
  • A separate incident, qtn3z0pny08n, prevented deployment of Workers and Workers for Platforms using nodejs_compat with a compatibility date on or after 4 August 2026.
  • Cloudflare told users to remove nodejs_compat as a temporary way around the deployment assertion, then resolved that incident at 03:03:00 UTC.
  • Cloudflare disclosed neither incident’s technical root cause, affected population, customer damage or preventive release-control changes, and did not say the incidents were related.

One release changed what code believed existed

The runtime incident was not simply a clock that ran slowly. Cloudflare said the latest Workers Runtime API release exposed a global Temporal entity that was not meant to be available. Capability detection therefore returned a different answer: code could conclude that a native time API existed even though its clock was fixed at the Unix epoch.

That distinction explains the silent failure path. Some Workers installed a polyfill only when Temporal was absent. Once the new global appeared, those Workers could stop installing the known implementation and begin using the faulty one. Cloudflare said no error was raised. A token could be issued at time zero and expire in 1970; a TTL or date calculation could be equally wrong while the Worker remained responsive.

Date and Date.now() were not affected. The boundary matters because this was not evidence that every time function in Workers failed, nor that every Worker used Temporal. Exposure depended on application logic, capability detection and the presence of a conditional polyfill.

The second incident sat before runtime

The deployment incident operated at a different stage. Workers and Workers for Platforms using the nodejs_compat compatibility flag with a compatibility date on or after 4 August were disallowed. The code did not first deploy and then misbehave; the control plane refused the named configuration.

Cloudflare said it was working to relax the assertion and advised removing the flag to avoid the error. That was an avoidance instruction, not evidence that every affected application could safely run without Node.js compatibility. A flag can stand for APIs and behaviours on which a Worker relies. Removing it without testing might exchange a visible deployment failure for a less visible runtime difference.

The incident lasted 4,000.289 seconds from opening to resolution. Cloudflare did not publish the number of rejected deployments, whether all regions were equally affected or what checks changed before the assertion was relaxed.

Compatibility dates are an operational interface

Compatibility dates are designed to let a platform evolve without forcing every application to adopt new behaviour at once. They are therefore more than documentation. They are part of the contract used by build systems, deployment policies and rollback procedures.

The 4 August assertion shows the downside when the contract itself becomes the fault surface. A team following the published mechanism—setting a current date and a required compatibility flag—could be blocked precisely because of that combination. A release process that tests individual flags but not representative flag-and-date matrices can miss this class of regression.

Customers should test future dates before their main release window, keep a last-known-good compatibility date and record which APIs genuinely require each flag. That does not transfer responsibility for the platform fault to the customer. It creates a bounded recovery option while the provider repairs the control plane.

Capability detection needs semantic tests

The Temporal incident reveals a related weakness in a common defensive pattern: “if the global exists, use it.” Presence is not correctness. A native entity can be incomplete, wrongly initialised or semantically incompatible with the polyfill it displaces.

A stronger start-up check would test a small invariant, such as whether the reported instant is within an acceptable distance of another trusted clock, before selecting the implementation. Critical token and expiry paths can also reject impossible dates rather than emitting plausible-looking but invalid output. Those controls cost code and test effort, but they protect the boundary where an upstream capability silently changes meaning.

They also need care. Date.now() was correct in this incident, but that does not make it a universal independent clock. The lesson is to validate the semantic assumption on which the application depends, not to declare one API permanently authoritative.

Resolution does not describe consequence

The runtime incident remained open for 57,547.538 seconds, from 15:13:33 UTC on 3 August to 07:12:40 UTC on 4 August. Cloudflare said the faulty global had been exposed since 30 July, so the possible application-level exposure began before the incident clock. The status history does not say how many Workers used the conditional pattern or whether the example errors became realised customer harm.

Similarly, a resolved deployment incident does not reveal how many releases missed a window, how many teams removed the flag or whether any workaround introduced a different problem. Status pages provide lifecycle evidence; they rarely provide a complete impact ledger.

The useful customer record is therefore local: failed deployment attempts, Workers that observed the global, tokens or TTLs produced during the exposure, downstream rejections and remedial rotation or recalculation. Without those measures, “minor” remains Cloudflare’s incident classification rather than a quantified statement about each customer.

Two incidents should not become one invented cause

Both events concerned Workers releases and closed on the same date. That proximity is enough to justify examining release governance, but not enough to claim one bad rollout, one team or one technical defect caused both. Cloudflare did not establish such a link.

The common analytical surface is the contract between platform change and customer automation. One regression changed runtime capability semantics; the other rejected a deployment configuration. Both can defeat a pipeline that checks only for HTTP availability. They require separate canaries: semantic runtime probes for the first, and forward-date deployment tests for the second.

That is a stronger conclusion than simply calling the platform unreliable. It identifies observable controls without exceeding the evidence.

Sources