vikrant69g blog

The SQLite bug that hid in plain sight for 16 years

Tailscale traced database corruption back to a WAL-mode edge case that survived billions of deployments since 2010.

Abstract visualisation of database corruption with fragmented data blocks and timing windows

Tailscale engineers spent weeks chasing phantom database corruption in their coordination server. The symptoms were rare, reproducible only under load, and pointed to SQLite eating its own state. Turns out the culprit was a write-ahead logging bug introduced in SQLite 3.7.0 in 2010. The bug lives in WAL mode, which most production systems use because it allows concurrent reads during writes. When SQLite resets the WAL file after a checkpoint, it zeroes the header but keeps the old frame data intact. If a reader opens the database between the header reset and the next write, it sees a valid-looking WAL with a zero-length header and stale frames. SQLite interprets this as corruption and bails. What makes this brutal is the timing window. It only triggers if a process opens the database file in the microseconds between WAL reset and the next transaction commit. On a quiet system, that window never opens. On a system handling thousands of requests per second with dozens of processes hammering the same database, it becomes inevitable. SQLite is in everything. Browsers, phones, embedded devices, half the desktop apps you have open right now. It has been through more fuzz testing than most codebases will ever see. And yet this edge case survived 16 years because the conditions to hit it are pathological. You need WAL mode, you need checkpointing, you need multiple processes, and you need them to collide in a window measured in microseconds. Tailscale reported it. The SQLite team fixed it in under 48 hours. The patch is already in trunk. But the bug is still live in every SQLite binary built before August 2026, which is approximately all of them. This is the kind of bug that makes you paranoid about what else is hiding in systems we assume are bulletproof.


Source: Tailscale Traces Database Corruption to 16y/o SQLite WAL-Reset Bug