16-year-old SQLite bug traced to Tailscale's 2025 database corruption
Tailscale has traced a year of intermittent database corruption to a 16-year-old race condition in SQLite's write-ahead log checkpointing, present in the database engine since version 3.7.0 shipped in July 2010.
The company's control plane runs SQLite to manage its virtual mesh networks, and starting in August 2025 it began seeing databases corrupt during backup runs. Engineer Alex Chan said the team spent six months ruling out POSIX file locks, memory handling, and threading bugs before finding the real cause: "If a write occurs at a specific time during a checkpoint, the checkpointing process gets confused, it thinks some of the pages have been copied from the WAL into the main database file, but they haven't."
The trigger was Tailscale's own setup. Standard SQLite deployments let the engine handle checkpoint timing automatically. Tailscale took manual control of checkpointing to run an aggressive backup schedule, which pushed the software down a code path few other users exercise and exposed the dormant race condition. "By taking manual control of the checkpointing process and running at our own aggressive pace, we stepped off the well-trodden operational path," Chan said.
Finding it took a custom tool: SQLite's maintainers built a dedicated virtual file system logger to trace exactly when checkpoint operations touched WAL pages, work that took nearly as long as the investigation itself. SQLite has since shipped a patch closing the bug.
The incident is a reminder that any manual override of a database's default operational behavior, however small, can walk straight into edge cases the software was never tested against. Teams running SQLite with custom checkpoint or backup logic should treat that configuration as non-standard and worth extra scrutiny.