{"record":{"id":"d14f83b9f0fe985f","repo":"kopia/kopia","slug":"upgrade-lock-intent","errorCode":null,"errorMessage":"upgrade lock intent","messagePattern":"upgrade lock intent","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"repo/open.go","lineNumber":496,"sourceCode":"\t\t\tm.RUnlock()\n\t\t\treturn nil\n\t\t}\n\n\t\tm.RUnlock()\n\n\t\t// upgrade the lock and verify again in-case someone else won the race to refresh\n\t\tm.Lock()\n\t\tdefer m.Unlock()\n\n\t\tltime := fmgr.LoadedTime()\n\n\t\tif lastCheckTime.Equal(ltime) {\n\t\t\treturn nil\n\t\t}\n\n\t\tuli, err := fmgr.UpgradeLockIntent(ctx)\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"upgrade lock intent\")\n\t\t}\n\n\t\tif err := handleMissingRequiredFeatures(ctx, fmgr, ignoreMissingRequiredFeatures); err != nil {\n\t\t\tonFatalError(err)\n\t\t\treturn err\n\t\t}\n\n\t\tif uli != nil {\n\t\t\t// only allow the upgrade owner to perform storage operations\n\t\t\tif locked, _ := uli.IsLocked(now()); locked && upgradeOwnerID != uli.OwnerID {\n\t\t\t\treturn ErrRepositoryUnavailableDueToUpgradeInProgress\n\t\t\t}\n\t\t}\n\n\t\tlastCheckTime = ltime\n\n\t\treturn nil\n\t}","sourceCodeStart":478,"sourceCodeEnd":514,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/repo/open.go#L478-L514","documentation":"Raised inside the upgrade-lock monitor: when it is time to re-check the upgrade lock, fmgr.UpgradeLockIntent(ctx) is called to read any in-progress repository format-upgrade intent from the format blob; any error is wrapped as 'upgrade lock intent'. It indicates the monitor could not determine whether another client is performing (or has aborted) a format upgrade.","triggerScenarios":"A repository open/periodic check finds the previous lock check stale (lastCheckTime != ltime) and attempts to refresh UpgradeLockIntent; the read of the format blob (or API in server mode) fails.","commonSituations":"Storage backend temporarily unreachable during a long-running session; concurrent client performing an upgrade lock causing read contention; corrupted format blob; expired credentials mid-session.","solutions":["Check the wrapped cause for the concrete read failure.","Verify storage connectivity/credentials and let the monitor retry on the next tick.","If another client holds an upgrade lock, wait for the upgrade to finish (kopia repository status shows upgrade intent).","If the upgrade intent is stale (crashed client), clear it per Kopia docs (kopia repository upgrade ... / manual format blob cleanup)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Go: check for an active upgrade intent before long-running operations\nintent, err := fmgr.UpgradeLockIntent(ctx)\nif err == nil && intent.OwnerID != \"\" {\n    return errors.New(\"another client is upgrading the repository; wait and retry\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"upgrade lock intent\") {\n    if isTransientStorageError(err) { return retryWithBackoff(ctx) }\n    return fmt.Errorf(\"check upgrade-lock state manually: %w\", err)\n}","preventionTips":["Avoid running repository upgrades concurrently with normal operations.","Monitor storage connectivity for long-running sessions.","Clean up stale upgrade-lock intents after crashed upgrades.","Use stable credentials so mid-session auth cannot expire."],"tags":["kopia","upgrade-lock","format-blob","concurrency"],"backgroundTag":"file-read-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}