A 16-year-old SQLite bug ate Tailscale's data
Tailscale hit 19 database corruptions in six months. The cause was a SQLite WAL race from 2010, triggered because they used SQLite in a non-standard way.
Tailscale spent six months chasing database corruption it could not reproduce. The cause turned out to be a SQLite bug that had been sitting in the code since 2010 — a race between a checkpoint and a write transaction that silently drops pages. The lesson they drew from it is the part worth stealing: boring technology stops being boring the moment you use it in a non-standard way.
What actually happened
Per Tailscale's own write-up, corruption incidents started in August 2025 and ran to 19 separate instances, including a six-week false calm that made the hunt worse. SQLite's developers named it the WAL-Reset bug and estimate it had been present for at least 16 years, since WAL mode landed in SQLite 3.7.0.
The mechanic: if a write lands at exactly the wrong moment during a checkpoint, the checkpointer believes pages have been copied from the write-ahead log into the main database file when they have not. The pages never get written. References to them do. The data is gone, permanently, and nothing errors at the time.
It stayed hidden for 16 years because it is genuinely rare — and Tailscale found it because they take manual control of checkpointing to run fast, consistent backups. That is an unusual thing to do with SQLite, and it dialed the odds up until the race started firing. The fix required SQLite's team to build a new virtual-filesystem logging shim, funded by Tailscale, to capture what happened during a faulty checkpoint. The fix shipped in SQLite 3.51.3. The Register has the outsider's version if you want it shorter.
Why this matters for your business
SQLite is probably in your stack whether you chose it or not — it is under your mobile app, your desktop tooling, half your dependencies, and increasingly under per-object serverless storage. Step one is boring and immediate: find out what version you are pinned to and get to 3.51.3 or later.
Step two is the real takeaway. Tailscale's phrasing is that running boring technology in a non-standard way is a risk, and that is the sentence to keep. The safety of a mature dependency comes from millions of people hitting the same code paths in the same order. Take the well-tested path and you inherit their testing. Step off it — manual checkpoints, a custom VFS, an exotic connection pool, a clever write pattern someone added for speed — and you are now the person doing QA on that combination, at your own expense, in production.
That does not mean never deviate. It means price it. When we build something that uses a common tool in an uncommon way, that decision gets written down, gets a detection for the failure mode it might cause, and gets revisited. Tailscale's ending is the model here: after patching, they deployed a warning log for checkpoint-write overlap. Two months later it fired — proof the bug had been live all along, and proof the fix was holding.
Key takeaways
- A data race between checkpoint and write in SQLite's WAL mode caused 19 corruption incidents at Tailscale over six months; the bug dates to 2010
- Corrupted pages vanish silently — no error at write time, which is why it took six months and a purpose-built VFS logging shim to catch
- The fix is in SQLite 3.51.3; check what version your app and your dependencies actually bundle
- Manual checkpointing is unusual, and that is exactly why Tailscale hit a 16-year-old bug — non-standard use of standard tools makes you the tester
- When you must deviate, ship a detection for the failure mode you're inviting, the way Tailscale added overlap warnings
Got a clever workaround holding up production? We audit the places a system uses ordinary tools in extraordinary ways, and add the detection that turns a silent failure into a page. Send us the part that worries you or see what we've built and hardened.
Sources: Tailscale, The Register.
- #sqlite
- #tailscale
- #data-corruption
- #wal
- #engineering
Tommy Rush — Founder, Rush Commerce
Operator turned builder. 15+ years running operations — now shipping the systems businesses run on. More
Get The Rush Report weekly — one email, zero fluff.
Keep reading
ShieldBreak: a Windows Defender zero-day with no patch
An unpatched Windows Defender flaw hands local users SYSTEM privileges on Windows 10, 11, and Server 2025. No fix exists, so detection is the control you have.
Read itSignal's key transparency: proof beats a vendor promise
Signal shipped Automatic Key Verification with Cloudflare and Trail of Bits as outside auditors. The pattern applies to any system you ask people to trust.
Read it