AdguardTeam/AdGuardHome · error
decoding old db: %w
Error message
decoding old db: %w
What it means
Raised by readOldDB during lease-database migration when the legacy lease file (usually /opt/adguardhome/data/leases.db or workdir equivalent) exists but does not contain valid JSON for []*leaseJSON. Migration aborts, leaving the old file untouched.
Source
Thrown at internal/dhcpd/migrate.go:57
// readOldDB reads the old database from the given path.
func readOldDB(path string) (leases []*leaseJSON, err error) {
// #nosec G304 -- Trust this path, since it's taken from the old file name
// relative to the working directory and should generally be considered
// safe.
file, err := os.Open(path)
if errors.Is(err, os.ErrNotExist) {
// Nothing to migrate.
return nil, nil
} else if err != nil {
// Don't wrap the error since it's informative enough as is.
return nil, err
}
defer func() { err = errors.WithDeferred(err, file.Close()) }()
leases = []*leaseJSON{}
err = json.NewDecoder(file).Decode(&leases)
if err != nil {
return nil, fmt.Errorf("decoding old db: %w", err)
}
return leases, nil
}
// migrateDB migrates stored leases if necessary.
func migrateDB(conf *ServerConfig) (err error) {
defer func() { err = errors.Annotate(err, "migrating db: %w") }()
oldLeasesPath := filepath.Join(conf.WorkDir, dbFilename)
dataDirPath := filepath.Join(conf.DataDir, dataFilename)
oldLeases, err := readOldDB(oldLeasesPath)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return err
} else if oldLeases == nil {
// Nothing to migrate.View on GitHub (pinned to b41aefbe51)
Solutions
- Back up and inspect the old DB: python3 -m json.tool /path/leases.db to locate the syntax error
- If unrecoverable, move leases.db aside (mv leases.db leases.db.bak) — you lose old leases but migration proceeds on next start
- Restore from a pre-migration backup if the leases matter
- Report the schema upstream if the JSON is valid but structurally different from leaseJSON
Defensive patterns
Strategy: fallback
Validate before calling
if _, err := os.Stat(oldDBPath); err == nil {
if b, _ := os.ReadFile(oldDBPath); !json.Valid(b) {
// back it up before starting the server
os.Rename(oldDBPath, oldDBPath+".corrupt")
}
} Try / catch
if err := migrateDB(...); err != nil {
if strings.Contains(err.Error(), "decoding old db") {
// preserve old file, continue with empty lease set, restore from backup
}
} Prevention
- Back up the workdir (leases.db) before upgrades
- Never hand-edit the lease database
- Monitor disk space — truncated writes from full disks are the usual corruption source
When it happens
Trigger: Starting AdGuard Home with an old-format lease file that is empty, truncated (crash during a previous write), hand-edited with a syntax error, or in a prehistoric incompatible format.
Common situations: Upgrading from a very old AdGuard Home version whose schema differs; a power loss corrupting leases.db mid-write; operators hand-editing the lease file; a zero-byte file left by a failed disk-full write.
Related errors
- decoding db: %w
- starting dhcp server: %w
- bad dhcpv4 configuration: %w
- dhcpv4 or dhcpv6 configuration must be complete
- decoding json: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/7a7468a1b0b18369.
Report an issue: GitHub.