{"record":{"id":"648691be0a4913cc","repo":"juanfont/headscale","slug":"headscale-version-s-cannot-be-used-with-a-databas-648691","errorCode":null,"errorMessage":"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","messagePattern":"headscale version (.+?) cannot be used with a database last used by (.+?), upgrading more than one minor version at a time is not supported, please upgrade to the latest v(.+?)\\.(.+?)\\.x release first, then to (.+?), release page: https://github\\.com/juanfont/headscale/releases: %w","errorType":"console","errorClass":"errVersionUpgrade","httpStatus":null,"severity":"critical","filePath":"hscontrol/db/versioncheck.go","lineNumber":258,"sourceCode":"\t\t\t\"headscale version %s cannot be used with a database last used by %s: %w\",\n\t\t\tcurrentVersion, storedVersion, errVersionMajorChange,\n\t\t)\n\t}\n\n\tminorDiff := current.Minor - stored.Minor\n\n\tswitch {\n\tcase minorDiff == 0:\n\t\t// Same minor version — patch changes are always fine.\n\t\treturn nil\n\n\tcase minorDiff == 1:\n\t\t// Single minor version upgrade — allowed.\n\t\treturn nil\n\n\tcase minorDiff > 1:\n\t\t// Multi-minor upgrade — blocked.\n\t\treturn fmt.Errorf(\n\t\t\t\"headscale version %s cannot be used with a database last used by %s, \"+\n\t\t\t\t\"upgrading more than one minor version at a time is not supported, \"+\n\t\t\t\t\"please upgrade to the latest v%d.%d.x release first, then to %s, \"+\n\t\t\t\t\"release page: https://github.com/juanfont/headscale/releases: %w\",\n\t\t\tcurrentVersion, storedVersion,\n\t\t\tstored.Major, stored.Minor+1,\n\t\t\tcurrent.String(),\n\t\t\terrVersionUpgrade,\n\t\t)\n\n\tdefault:\n\t\t// minorDiff < 0 — any minor downgrade is blocked.\n\t\treturn fmt.Errorf(\n\t\t\t\"headscale version %s cannot be used with a database last used by %s, \"+\n\t\t\t\t\"downgrading to a previous minor version is not supported, \"+\n\t\t\t\t\"release page: https://github.com/juanfont/headscale/releases: %w\",\n\t\t\tcurrentVersion, storedVersion,\n\t\t\terrVersionDowngrade,","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/hscontrol/db/versioncheck.go#L240-L276","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// In deployment scripts, gate upgrades to at most one minor per step:\nif current.Minor-stored.Minor > 1 {\n    return fmt.Errorf(\"upgrade stepwise: first install v%d.%d.x\", stored.Major, stored.Minor+1)\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, errVersionUpgrade) {\n    // parse the message's suggested intermediate version, install it,\n    // run migrations, then upgrade again — never skip or force\n}","preventionTips":["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."],"tags":["versioning","database","migration","upgrade","startup"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}