AdguardTeam/AdGuardHome · error
parsing expiry time: %w
Error message
parsing expiry time: %w
What it means
A stored dynamic lease's Expiry field is not a valid RFC3339 timestamp, so it cannot be converted to time.Time. Static leases are exempt (expiry skipped when IsStatic is true).
Source
Thrown at internal/dhcpd/db.go:79
Hostname: l.Hostname,
HWAddr: l.HWAddr.String(),
IP: l.IP,
IsStatic: l.IsStatic,
}
}
// toLease converts *dbLease to *dhcpsvc.Lease.
func (dl *dbLease) toLease() (l *dhcpsvc.Lease, err error) {
mac, err := net.ParseMAC(dl.HWAddr)
if err != nil {
return nil, fmt.Errorf("parsing hardware address: %w", err)
}
expiry := time.Time{}
if !dl.IsStatic {
expiry, err = time.Parse(time.RFC3339, dl.Expiry)
if err != nil {
return nil, fmt.Errorf("parsing expiry time: %w", err)
}
}
return &dhcpsvc.Lease{
Expiry: expiry,
IP: dl.IP,
Hostname: dl.Hostname,
HWAddr: mac,
IsStatic: dl.IsStatic,
}, nil
}
// dbLoad loads stored leases.
func (s *server) dbLoad() (err error) {
data, err := os.ReadFile(s.conf.dbFilePath)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("reading db: %w", err)View on GitHub (pinned to b41aefbe51)
Solutions
- Fix expiry values to RFC3339 format with timezone (2026-01-02T15:04:05Z)
- Remove the leases file to force re-learning of dynamic leases
- Check for and fix truncated/corrupted files
Example fix
// before
{"Expiry": "2026-01-02 15:04:05"}
// after
{"Expiry": "2026-01-02T15:04:05Z"} Defensive patterns
Strategy: validation
Validate before calling
if !dl.IsStatic {
if _, err := time.Parse(time.RFC3339, dl.Expiry); err != nil { /* drop lease */ }
} Type guard
func isRFC3339(s string) bool { _, err := time.Parse(time.RFC3339, s); return err == nil } Prevention
- Use RFC3339 with timezone in any tooling that writes leases
- Stop the service before editing the DB
When it happens
Trigger: Loading the lease DB where a non-static lease has an empty, truncated, or non-RFC3339 Expiry string (e.g. missing timezone offset).
Common situations: Hand-edited lease files, corruption, or a version change in date format; expiry set to 0 or unix epoch integer instead of RFC3339.
Related errors
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/88f0f36af0c4b819.
Report an issue: GitHub.