SQLITE_BUSY_RECOVERYWARNINGTier 2 — Caution⚠️ MEDIUM confidenceBusy: another connection is recovering WAL
Category: LockingVersions: 3.7.0+
🔴 Production Risk Error
Low — transient; resolves once WAL recovery finishes.
What this means
SQLITE_BUSY_RECOVERY (261) is an extended code returned when a database is in WAL mode and another connection is currently performing crash recovery (replaying the WAL). The caller should wait and retry.
Why it happens
- 1Application restarted after a crash; first connection to open the WAL database is performing recovery.
- 2Another process is replaying uncommitted WAL frames after an unclean shutdown.
How to reproduce
WAL-mode database open after an unclean shutdown with concurrent connections.
trigger — this will ERROR
import sqlite3, time
for attempt in range(5):
try:
conn = sqlite3.connect('my.db', timeout=5)
conn.execute('SELECT 1')
break
except sqlite3.OperationalError as e:
if 'database is locked' in str(e):
time.sleep(0.5)Transient; retries succeed once recovery completes.
Fix 1
Why this works
Retry with exponential backoff — recovery completes quickly in most cases.
Fix 2
Why this works
Set a reasonable connection timeout: sqlite3.connect("my.db", timeout=10)
Version notes
Sources
📚 Official docs: https://www.sqlite.org/rescode.html#busy_recovery
🔧 Source ref: sqlite3.h — SQLITE_BUSY_RECOVERY = 261
📖 Further reading: WAL mode
Confidence assessment
⚠️ MEDIUM confidence
Stable.
See also
⚙️ This error reference was generated with AI assistance and reviewed for accuracy. Examples are provided to illustrate common scenarios and may not cover every case. Always test fixes in a development environment before applying to production. Spotted an error? Suggest a correction →