juanfont/headscale · critical · errVersionUpgrade
headscale version %s cannot be used with a database last use
Error message
headscale version %s cannot be used with a database last used by %s, upgrading more than one minor version at a time is not supported, please upgrade to the latest v%d.%d.x release first, then to %s, release page: https://github.com/juanfont/headscale/releases: %w
What it means
The version check allows at most ONE minor version upgrade per step; this database was last used by a release more than one minor version older than the running binary. Skipping minors is blocked because migrations are only guaranteed chainable one minor at a time. The sentinel errVersionUpgrade is wrapped, and the message tells you exactly which intermediate version to install first (v<major>.<storedMinor+1>.x).
Source
Thrown at hscontrol/db/versioncheck.go:258
"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.
return fmt.Errorf(
"headscale version %s cannot be used with a database last used by %s, "+
"upgrading more than one minor version at a time is not supported, "+
"please upgrade to the latest v%d.%d.x release first, then to %s, "+
"release page: https://github.com/juanfont/headscale/releases: %w",
currentVersion, storedVersion,
stored.Major, stored.Minor+1,
current.String(),
errVersionUpgrade,
)
default:
// minorDiff < 0 — any minor downgrade is blocked.
return fmt.Errorf(
"headscale version %s cannot be used with a database last used by %s, "+
"downgrading to a previous minor version is not supported, "+
"release page: https://github.com/juanfont/headscale/releases: %w",
currentVersion, storedVersion,
errVersionDowngrade,View on GitHub (pinned to 565fd254d0)
Solutions
- Install the latest patch release of the intermediate minor version named in the message (v<major>.<storedMinor+1>.x), start headscale once so it migrates, then repeat stepwise until at the target version.
- Get releases from https://github.com/juanfont/headscale/releases as the message instructs.
- If the data is disposable, start with a fresh database instead.
- Back up the database file / dump before any stepwise migration.
Defensive patterns
Strategy: validation
Validate before calling
// In deployment scripts, gate upgrades to at most one minor per step:
if current.Minor-stored.Minor > 1 {
return fmt.Errorf("upgrade stepwise: first install v%d.%d.x", stored.Major, stored.Minor+1)
} Try / catch
if errors.Is(err, errVersionUpgrade) {
// parse the message's suggested intermediate version, install it,
// run migrations, then upgrade again — never skip or force
} Prevention
- Upgrade one minor version at a time, running headscale between steps.
- Take a DB backup/dump before each step of a multi-hop upgrade.
- Let CI or scripts verify stored version vs binary version before swapping binaries.
When it happens
Trigger: Upgrading e.g. from v0.23 directly to v0.26 (minorDiff > 1): the binary starts, reads the stored version, and refuses to migrate. Also happens when a database file from an old install is reused with a much newer binary.
Common situations: Long-lived deployments jumping several releases at once; package managers (apt/brew) pulling the latest version far ahead of the installed one; containers updated many versions past the data volume's version.
Related errors
- version check: %w
- headscale version %s cannot be used with a database last use
- headscale version %s cannot be used with a database last use
- automigrating types.Route: %w
- checking if table %s exists: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/648691be0a4913cc.
Report an issue: GitHub.