DEV Community

Kashif Manzer
Kashif Manzer

Posted on

GitHub Is Failing Your macOS Builds on Purpose This Month

GitHub Is Failing Your macOS Builds on Purpose This Month

Monday morning. You open your laptop and your CI is red.

Nobody shipped anything over the weekend. The diff is empty. You re-run the workflow, and it fails again. You re-run it once more for luck, and it fails a third time. Then, late in the afternoon, with no changes at all, it turns green.

Your first instinct is to blame the cache. Your second instinct is to blame yourself. Both are wrong.

GitHub did this on purpose.

What a brownout is

GitHub is retiring the macOS 14 runner image on November 2, 2026. That is the Sonoma-based virtual machine your workflow gets when the job says runs-on: macos-14.

Before the image goes away, GitHub is running brownouts: scheduled windows where every job on the macOS 14 labels fails on purpose. Not because something is broken. To make something visible.

A brownout is the opposite of an outage. An outage is failure you did not plan. A brownout is failure you scheduled, announced, and documented, because you are more scared of the quiet kind. The quiet kind is a workflow that pins an old image and nobody notices until the retirement date, when it fails for real and there is no window left to fix it.

The schedule

There are eight windows, each ten hours, 14:00 UTC to 00:00 UTC:

  • Oct 5 and 6 (this already happened)
  • Oct 12 and 13
  • Oct 16 and 17
  • Oct 19 and 20
  • Oct 23 and 24
  • Oct 26 and 27
  • Oct 29 and 30
  • Oct 30 and 31

In Pacific time that is 7:00am to 5:00pm. Most of the American workday falls inside the failure window. The windows cluster toward the end of the month, with two of them back to back, which is the part where patience runs out.

Inside a window, any job on macos-14, macos-14-large, or macos-14-xlarge fails deliberately. It does not matter that your workflow is fine. The failure is the message.

This applies to GitHub Actions and to Azure DevOps, because Microsoft-hosted agents are built from the same images.

Why the scheduled builds get hit first

Here is the cruel part of the design. The builds that turn red first are the ones nobody is watching.

Cron-scheduled workflows, nightly builds, matrix jobs that run across a fleet of repos at midnight: they fire right inside the window, and the first anyone hears about it is a red badge in the morning. A developer pushing at 10am sees the failure immediately and starts debugging. A scheduled job failing at 2am just sits there, red and unexamined, until standup.

That asymmetry is exactly why GitHub does it this way. A brownout that only ever failed while humans were watching would be ignorable. One that fills your mornings with red across repos you forgot about is not.

The quieter killer: the queue

There is a second, sneakier effect, and it runs even outside the windows. Since the deprecation was announced in July, GitHub has been allowed to reduce capacity for the macOS 14 runners. Fewer machines serving the same jobs means longer queue times.

So your macOS 14 jobs might not just fail in bursts. They might also sit waiting in the queue, for no reason your workflow file explains, getting slower and flakier all month. If your builds have been mysteriously slow since summer, this is probably why, and the brownouts are just the part GitHub put on a calendar.

The fix is one search away

Find every workflow that still asks for the old image:

grep -rn "macos-14" .github/workflows/
Enter fullscreen mode Exit fullscreen mode

Then move each one to a supported label:

jobs:
  build:
    runs-on: macos-15   # or macos-latest
Enter fullscreen mode Exit fullscreen mode

GitHub's named migration targets are macos-latest (currently macos-26), macos-15, and their -xlarge counterparts.

One warning before you swap the label and walk away. This is a real OS jump, not a version bump. Sonoma to Sequoia or newer means different Xcode and toolchain versions, different Homebrew and Clang versions, and anything your build quietly pinned to Sonoma behavior. Treat the first green run on the new image as suspicious. Run the full suite, check the artifacts, and re-verify anything that smells like it depended on the old machine.

The pattern worth keeping

Step back from the calendar for a second. What GitHub is doing here is chaos engineering with a courtesy notice. The industry spent a decade learning that the only way to find out what depends on a thing is to take the thing away on a schedule you control, rather than wait for it to disappear on a schedule you do not.

Netflix kills its own servers in the middle of the day for the same reason. GitHub kills your builds for ten hours at a time for the same reason. The lesson generalizes: every dependency you cannot name is a brownout you did not schedule.

November 2 is the real deadline. The brownouts are just the rehearsal, and the next rehearsal starts Monday at 7:00am Pacific.

So here is my question for you: what in your stack is still pinned to macOS 14, and why?

Top comments (0)