Bulletin C 72 is one page, dated Paris, 6 July 2026, and addressed "to authorities responsible for the measurement and distribution of time." Its operative line is "NO leap second will be introduced at the end of December 2026." The IERS sends one every six months, either to announce a step in UTC or to confirm there won't be one at the next possible date, which is the last second of June or of December. Airlines, DNS providers and anyone running a fleet of NTP clients read it, because twice in the last fifteen years the step it announced broke production systems.
Twenty-seven times since 1972 the world's clocks have shown 23:59:60, and the last time was 31 December 2016. A clock that's allowed to repeat a second breaks the forward-only assumption most time code makes, that now minus then is never negative. In 2012 the Linux kernel stepped its own clock back without telling its timer code, and in 2016 Cloudflare's DNS server subtracted across the step. The 28th General Conference on Weights and Measures met in Versailles from 13 to 15 October to vote on Draft Resolution C, which would stop inserting leap seconds on 20 May 2027 and let UTC drift up to an hour from the Earth's rotation before anything corrects it.
I read two public postmortems down to the line that failed: the Linux hrtimer bug of 2012, from John Stultz's message to the kernel list, and Cloudflare's DNS errors on 1 January 2017, from Cloudflare's own write-up. Then I cover the smearing schemes Google and Meta published and the text of the resolution, and I leave out the geophysics beyond what sets the dates.
Twenty-seven, then none
The IERS keeps the history as a file of dates and offsets. TAI minus UTC was 10 seconds on 1 January 1972 and is 37 seconds now, and each of the 27 steps in between added a second. None has ever removed one. Two came in 1972, at the end of June and the end of December, and then one every December from 1973 to 1979. The 1980s had June 1981, 1982, 1983 and 1985, then December 1987 and 1989.
The 1990s opened with December 1990 and June 1992, 1993 and 1994, followed by December 1995, June 1997 and December 1998. After that the list thins out: December 2005 and 2008, June 2012 and 2015, December 2016.
The longest gap between two insertions used to be seven years, December 1998 to December 2005. The current one reaches ten years at midnight on 31 December 2026, since Bulletin C 72 has already said that midnight passes with no step.
2012: the timer that fired early
The leap second of 30 June 2012 fell at 23:59:60 UTC, just before 10 a.m. on Sunday in Sydney. Amadeus's hosted Altea system, which runs check-in for Qantas and Virgin Australia among other airlines, went offline for an hour, and staff at both airlines checked passengers in by hand. Amadeus said the outage "was caused by the Linux bug triggered by the 'leap second'". Mozilla (its bug 769972), StumbleUpon, Yelp, Foursquare, Reddit and LinkedIn were reported hit by the same bug, and Reddit was unreachable for 30 to 40 minutes.
John Stultz posted the diagnosis to the kernel list on 1 July. The timekeeping core holds wall time. The high-resolution timer code, hrtimers, keeps its own offset for CLOCK_REALTIME, and a function called clock_was_set() refreshes that offset when the clock changes. Applying the leap second set CLOCK_REALTIME back one second without calling clock_was_set(). So the hrtimer offset stayed where it was, and the timer code's idea of wall time ran one second ahead of the core's.
From then on every absolute CLOCK_REALTIME timer (one armed with TIMER_ABSTIME) fired a second early. A timer set for less than a second out had already expired by the timer code's clock, so, in Stultz's words, "all sub-second TIMER_ABSTIME CLOCK_REALTIME timers will return immediately." Code that waits in a loop with a timeout, which is what a futex_wait caller does, came straight back and waited again, in a tight loop. On the LWN thread readers reported MySQL on a RHEL 6.2 server stuck burning CPU, and Java on CentOS 6.2 using "an insane amount of CPU due to timers expiring immediately."
Stultz wrote that the bug had likely been there since commit 746976a301ac in v2.6.22, from 2007, which removed a clock_was_set() call from the leap-second path to avoid a deadlock, and he reproduced the bug on v2.6.32.59, v2.6.37 and v3.5-rc4. The bad state lasted until something called clock_was_set(), and that is "most easily done via settimeofday()", so setting the clock to the time it already showed cleared it. His test program scheduled a leap second ten seconds out and slept in half-second clock_nanosleep loops for 30 seconds. On an affected kernel the output streamed past with negative differences. The fix, commit 4873fa0, calls clock_was_set_delayed() when the leap second is applied, deferring the update to softirq context because it can't run from a hard interrupt.
Stepping CLOCK_REALTIME back across the leap second is what POSIX time asks for. One commenter on the LWN thread put it as "the POSIX count assumes 60 seconds in every UTC minute, regardless of how long that minute actually lasts." The bug was in the notification: settimeofday() told the timer code when it changed the clock, and the leap-second path changed the clock without telling it.
2016: the duration that went negative
Cloudflare's DNS server, RRDNS, is written in Go. For customers using CNAME records it resolves through upstream servers and picks among them by weighted random choice, with the weights coming from recent round-trip times. It measured each round trip like this:
rtt := time.Now().Sub(start)At 00:00 UTC on 1 January 2017 the system clock went back one second. A lookup that started in the last second of 2016 and finished in the repeated one got a negative rtt. RRDNS smoothed the times over several measurements, and enough negative samples pulled the smoothed value below zero. That value went into the weighted selection, which passed it to rand.Int63n, and rand.Int63n panics on a negative argument. recover caught the panic in Go and the process kept running. The one lookup that hit it returned an error.
The postmortem's timeline is in UTC on 1 January. Impact began at 00:00. Engineers had it escalated to them at 00:10 and confirmed the issue at 00:34. A mitigation was deployed and confirmed on one canary node at 00:55 and in a canary data center at 01:03, and the fix reached the most affected data center at 01:23. Rollout to every data center began at 01:48, and impact ended at 06:45. At the peak about 0.2 percent of DNS queries to Cloudflare were affected and under 1 percent of HTTP requests returned an error, on a small number of machines across its 102 data centers.
The section on the fix is titled "The one character fix", and the patch is shown as an image of a two-line diff in the selection code: if rttMax == 0 { became if rttMax <= 0 {, so a zero or negative maximum is replaced with DefaultTimeout before it reaches the random draw. The post says it let RRDNS "forget about current upstream performance" and normalize again if time skipped backwards, which "prevents the recording of negative values in server selection." The post names the root cause as "the belief that time cannot go backwards." Go's time.Now() didn't guarantee monotonicity then, and the post points at Go issue 12914.
Go 1.9, released on 24 August 2017, came out of that issue's design. Every time.Time from time.Now() now carries a monotonic clock reading next to the wall time, and Sub uses the monotonic readings when both values have one. The same line is correct today, unless a value lost its monotonic reading. A time.Time that came from parsing, from a database or from Round(0) has no monotonic reading, and Sub on it falls back to wall time. A faithful reduction of the pattern, with a guard of the kind Cloudflare's fix added, for wherever the clock isn't monotonic:
start := time.Now() // wall time plus a monotonic reading (Go 1.9+)resp, err := query(upstream)rtt := time.Since(start) // monotonic: a clock step can't make this negativeif rtt <= 0 { return resp, err // drop the sample; never feed it to the smoother}smoother.Add(upstream, rtt)Smearing, and why it can't be shared
Google had hit the problem earlier. Christopher Pascoe's 2011 post says some of Google's clustered systems "stop[ped] accepting work on a small scale during the leap second in 2005." For the December 2008 leap second the site reliability team patched its internal Stratum 2 NTP servers to stop setting the Leap Indicator. Instead the servers told clients a small "lie" about the time that grew over a window w before midnight, lie(t) = (1.0 - cos(pi * t / w)) / 2.0. They tested it first with one negative and one positive smear on about 10,000 servers. By midnight every client clock had already absorbed the extra second, and nothing stepped.
Google's smear documentation gives the later versions. 2008 was a 20-hour cosine smear ending at the leap. 2012, 2015 and 2016 used a 20-hour linear smear centered on it. The current public recommendation is a 24-hour linear smear from noon to noon UTC: one extra second spread over 86,400 makes each smeared second about 11.6 microseconds longer than an SI second.
Meta published its scheme in July 2022, by Oleg Obleukhov and Ahmad Byagowi. It smears quadratically over 17 hours starting at 00:00:00 UTC, on hundreds of Stratum 2 NTP servers at once. The same post explains why that stays inside the company. Public NTP pools don't smear and sometimes pass a leap indicator through to clients, so "big players like Meta, who perform smearing on public services, can't join the public pools." Meta's conclusion was that leap seconds do "more harm than good" and that "it is time to introduce new technologies to replace it."
A server can step at midnight, stretch seconds evenly over 20 or 24 hours, or stretch them along a cosine or quadratic curve over 17 to 20 hours, and the windows don't even start at the same time. During the window two of these can disagree by up to a full second, and an NTP response has no field that says which one the server chose. Draft Resolution C names the cost directly: the "different mitigation methods" global providers use lead to "inconsistency in timing between different systems."
The strongest objection is that smearing already fixed this for the companies large enough to be hurt. Inside each company it did. Across companies it couldn't: Google's window runs noon to noon and Meta's starts at midnight, and the public pools don't smear at all. Google's 2008 test did run one negative smear, but no smear has met a real second removed instead of added, because none has ever been removed.
The vote in Versailles
The 27th CGPM, in 2022, adopted Resolution 4. It decided that the maximum value of |UT1 - UTC| "will be increased in, or before, 2035, to ensure the continuity of UTC for at least a century", and asked the CIPM to draft a resolution for the 28th meeting. That draft is Resolution C, "On the technical actions needed to ensure the continuity of UTC", approved by the CIPM in January, March and June 2026. It decides two things. Continuous UTC becomes effective on 20 May 2027, and the maximum |UT1 - UTC| becomes 3,600 seconds, one hour, "ensuring the long-term continuity for UTC for several centuries." The 28th CGPM met at the Palais des Congrès de Versailles from 13 to 15 October 2026.
The date moved forward from 2035 because the Earth has been turning faster. Every leap second so far was added because the day ran long against atomic time. A March 2025 workshop of the CCTF and the IERS estimated a 30 percent probability of a negative leap second, a minute of 59 seconds, by 2035. The resolution notes that a negative leap second "has not previously been applied" and poses "a high risk of causing anomalies and disruption to critical infrastructures that are largely unprepared."
Duncan Agnew's paper in Nature (628, 333 to 336, published 27 March 2024) explains part of why it hasn't happened yet. Faster melting of ice in Greenland and Antarctica, measured by satellite gravity, has slowed the Earth's rotation more than before. With that included, his extrapolation has UTC as now defined needing a negative step by 2029. Without the accelerated melt, the step would have come three years earlier, in 2026. On 5 July 2024 the Earth turned in 1.66 milliseconds less than 86,400 seconds, the shortest day on record. Meta's post gives what a negative leap second looks like on a clock: 23:59:58 followed directly by 00:00:00, with no 23:59:59 for a cron job or a log rotation scheduled at that second to fire on.
Reading a clock that may repeat
Measure durations on a monotonic clock: CLOCK_MONOTONIC in C, time.Since or Sub between two fresh time.Now() values in Go 1.9 or later. Never measure them as the difference of two stored wall timestamps. Wall time is a label for when something happened, for logs and for people, and it can repeat or skip. When a difference comes out zero or negative anyway, drop the sample or replace it with a default, as Cloudflare's fix did, rather than pass it to a smoother or a random-number call. And read Bulletin C when it comes out, in early January and early July.
The same distrust of wall-clock nearness decided a design in One Call, Two Ids. My usage collector sees each model call from two observers. The scanner that merges the duplicate rows accepts only an exact id association, and the later twin rule only a one-to-one match on the fields a call fixes, with occurred_at equal to the millisecond. Two different calls of the same size a second apart stay two rows.
What this doesn't settle
The vote's outcome isn't in this draft; it goes in the paragraph marked above once bipm.org publishes it. Cloudflare shows its patched code only as an image of a two-line diff, == to <=, without the code around it. The 2005 Google incident comes from Google's own post, which calls it small-scale and says it didn't affect the site or any data. The Altea outage length (an hour) is The Register's figure. The 2029 date is Agnew's extrapolation of the core and ice trends, and the 30 percent is a workshop estimate quoted in the resolution.
At midnight on 31 December the clocks run straight through, as the one-page bulletin from Paris says. Under Resolution C the next correction would wait until UT1 and UTC are an hour apart, which the resolution expects to take several centuries.