juanfont/headscale · critical · errVersionMajorChange
headscale version cannot be used with a database last used…
Error message
headscale version %s cannot be used with a database last used by %s: %w
What it means
The version compatibility check found that the database was last written by a headscale release with a different MAJOR version than the running binary. Major versions imply breaking schema changes, so headscale refuses to touch the database. The sentinel errVersionMajorChange is wrapped for programmatic detection.
Solutions
- Check the stored version (shown in the message) and the running binary version (headscale version).
- Follow the release notes for the major upgrade path — typically export/migrate data or start from the intermediate major version.
- If the database is disposable (test/dev), delete or move the SQLite file (or drop the Postgres database) and let headscale recreate it.
- Never hand-edit the stored version row to force compatibility.
Defensive patterns
Strategy: validation
Validate before calling
// Before starting, compare versions if you can read the stored version:
// (simplified; headscale does this internally at startup)
if current.Major != stored.Major {
return fmt.Errorf("refusing to run: database is from major version %d, binary is %d", stored.Major, current.Major)
} Try / catch
if err := db.CheckVersion(...); err != nil {
if errors.Is(err, errVersionMajorChange) {
// hard stop: export/migrate via the documented major-upgrade path or start fresh
log.Fatal().Err(err).Msg("incompatible database major version")
}
} Prevention
- Back up the database before any headscale upgrade.
- Pin versions in deployment tooling and read release notes before major bumps.
- Never share one database between installations of different major versions.
When it happens
Trigger: Starting a headscale vN binary against a database whose stored version has major != N — e.g. after a major release upgrade or downgrade, or pointing dns/db config at a database file from another headscale major version.
Common situations: Upgrading headscale across a major version boundary in one step; restoring a backup made by a different major version; two installations sharing one database file.
Related errors
- headscale version cannot be used with a database last used…
- headscale version cannot be used with a database last used…
- version check
- adding hash column
- adding prefix column
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/f28091ee5c2595c4.
Report an issue: GitHub.
Appendix: source
Thrown at hscontrol/db/versioncheck.go:239
}
// Previous run was an unversioned build — no meaningful comparison.
if isDev(storedVersion) {
return nil
}
current, err := parseVersion(currentVersion)
if err != nil {
return fmt.Errorf("parsing current version: %w", err)
}
stored, err := parseVersion(storedVersion)
if err != nil {
return fmt.Errorf("parsing stored database version: %w", err)
}
if current.Major != stored.Major {
return fmt.Errorf(
"headscale version %s cannot be used with a database last used by %s: %w",
currentVersion, storedVersion, errVersionMajorChange,
)
}
minorDiff := current.Minor - stored.Minor
switch {
case minorDiff == 0:
// Same minor version — patch changes are always fine.
return nil
case minorDiff == 1:
// Single minor version upgrade — allowed.
return nil
case minorDiff > 1:
// Multi-minor upgrade — blocked.View on GitHub (pinned to 565fd254d0)