AdguardTeam/AdGuardHome · error
opening database
Error message
opening database: %w
What it means
StatsCtx.New failed to open (or initialize) the underlying bbolt statistics database; s.openDB()'s error is wrapped as 'opening database'.
Solutions
- Verify the stats data directory exists and is writable by the process user
- Check for another running instance holding the bbolt file
- Remove/rename a corrupt stats DB file if the data is disposable
Defensive patterns
Strategy: try-catch
Validate before calling
if f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0o644); err != nil { return err }; f.Close() Try / catch
s, err := stats.New(conf)
if err != nil { log.Printf("stats init failed: %v", err); return err } Prevention
- Pre-create and chown the data directory
- Run one instance per data dir
- Monitor disk space
When it happens
Trigger: Calling stats.New when the DB file cannot be created/opened: bad path, permission denied, disk full, or a corrupt/locked database file.
Common situations: Working directory not writable, stats file owned by another user after running as root then as unprivileged user, two instances sharing the same data dir, or leftover lock.
Related errors
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/b69b76e6749008c9.
Report an issue: GitHub.
Appendix: source
Thrown at internal/stats/stats.go:189
configModifier: conf.ConfigModifier,
filename: conf.Filename,
confMu: &sync.RWMutex{},
ignored: conf.Ignored,
shouldCountClient: conf.ShouldCountClient,
limit: conf.Limit,
enabled: conf.Enabled,
}
if s.unitIDGen = newUnitID; conf.UnitID != nil {
s.unitIDGen = conf.UnitID
}
// TODO(e.burkov): Move the code below to the Start method.
err = s.openDB()
if err != nil {
return nil, fmt.Errorf("opening database: %w", err)
}
var udb *unitDB
id := s.unitIDGen()
tx, err := s.db.Load().Begin(true)
if err != nil {
return nil, fmt.Errorf("opening a transaction: %w", err)
}
deleted := s.deleteOldUnits(tx, id-uint32(s.limit.Hours())-1)
udb = s.loadUnitFromDB(tx, id)
err = finishTxn(tx, deleted > 0)
if err != nil {
s.logger.Error("finishing transacation", slogutil.KeyError, err)
}
View on GitHub (pinned to b41aefbe51)