2026-09-08 · 5 min read

Every 30GB Zune froze on the last day of 2008 because of a dozen lines with no else branch

On the morning of 31 December 2008, 30GB Zunes all over the world booted, showed the Microsoft logo, and stopped. Not crashed, not rebooted, just sat there, with a full battery, doing nothing, on the one day of the year people were actually going to use it. Microsoft's official advice was to let the battery drain completely and charge it again after noon GMT on New Year's Day, at which point the device would work fine, because by then it would no longer be the 366th day of a leap year. The whole story is a dozen lines of C, and I think it's the best code review exercise ever produced by accident.

The dozen lines

The clock driver on that model came from the power-management chip's vendor, and within hours of the freeze a ZuneBoards user going by itsnotabigtruck had pulled the function apart. It converts a count of days since 1 January 1980 into a year, by walking forward one year at a time:

rtc.c (Freescale MC13783 driver, as reconstructed on ZuneBoards)
year = ORIGINYEAR; /* = 1980 */
while (days > 365)
{
    if (IsLeapYear(year))
    {
        if (days > 366)
        {
            days -= 366;
            year += 1;
        }
    }
    else
    {
        days -= 365;
        year += 1;
    }
}

Trace 31 December 2008 through it. By the time the walk reaches 2008 the remaining count is exactly 366, because 2008 is a leap year and this is its last day. The outer while (days > 365) is true. IsLeapYear(2008) is true. days > 366 is false. And there's no else. So nothing is subtracted, nothing is incremented, the loop goes round again with the same values, and it will keep doing that until the heat death of the universe or the battery, whichever comes first. The battery came first, which is why draining it was the fix: at midnight the day counter ticked to 367, the inner branch became true, and the loop exited like it had every other day for two years.

The SEI's C coding standard now uses this exact function as its example for "strive for logical completeness," which is a polite way of saying every if inside a loop needs an answer for the case where it's false.

Why it only hit the 30GB model

This is the part I find genuinely funny. The bug wasn't in Microsoft's code at all. The Zune 30 was built on a Toshiba design and used a Freescale power-management chip whose real-time-clock driver contained the loop above; Microsoft's own statement said it was "a bug in a driver for a part that is only used in the Zune 30 device." Later Zunes used a different chip. Toshiba's own Gigabeat S player, which shared the same part and driver, froze on the same day. So a leap-year bug written by a chip vendor took out two product lines from two companies, and Microsoft got all the headlines because it was the one with a marketing budget.

Which is also a supply-chain point that's aged well: the code you ship is the code you ship, whoever typed it. In 2008 that meant a vendor driver. In 2026 it more often means a model, and the response to "but I didn't write that part" is the same in both cases, which is that you approved it.

The same bug, as a PR in front of you

We rebuilt the mechanism in the library as a Node PR: a device clock helper with the same forward-walking loop, a requirement that it terminates for every valid input "including the last day of a leap year," and a PR description that says it handles leap years and was checked against a range of sample day counts. All true. The samples just didn't include day 366.

Convert a device day count to a calendar year · src/clock/year.js +27
11+function dayCountToYear(days) {
12+ let year = EPOCH_YEAR;
14+ while (days > 365) {
15+ if (isLeapYear(year)) {
16+ if (days > 366) {
17+ days -= 366;
18+ year += 1;
19+ }
20+ } else {
21+ days -= 365;
22+ year += 1;
23+ }
24+ }
26+ return year;
What a trained eye flags here

The comment is one sentence long: "line 16, when days is exactly 366 in a leap year neither branch runs and the loop never makes progress; needs an else { break; } since day 366 belongs to the current year, and a test for the last day of a leap year." That's the whole review. If you want the reflex that produces it, it's the one from our off-by-one page: for every branch inside a loop, ask which path makes progress toward the exit, and then feed the loop the boundary value on purpose.

Review the PR yourself if you'd rather find out cold. The library doesn't tell you which incident it's based on until after your verdict.

What makes this one worth practicing on

Most famous bugs are famous because of the blast radius, and the mechanism is some subtle interaction you'd never spot in a diff. This one is the opposite. The blast radius was two product lines of MP3 players being useless for a day, and the mechanism is fully visible in a dozen lines, requires no context, no knowledge of the surrounding system, and no security expertise. It is, to my mind, the purest possible test of whether a reviewer actually traces boundary values through a loop or just reads the loop and thinks "yep, that handles leap years."

And here's the uncomfortable bit. The code does handle leap years. It subtracts 366 for them. It has a dedicated branch. A reviewer skimming for whether leap years were considered would find clear evidence that they were, and approve. The bug lives in the one input for which the code does nothing, and the only way to see it is to stop reading and start executing, in your head, with the worst number you can think of. For a day counter, the worst number is the last day of a leap year. Every four years, that number arrives.

Try a review

Handles leap years. Does nothing on day 366.

Review the Zune-mechanism PR and 200+ others with planted bugs. Free, no signup. Canonical review after your verdict.

Review this PR →
Read next Off-by-one errors in code review: five shapes, twelve PRs, and why round test data hides all of them
← All posts