kopia/kopia · error
upgrade lock intent
Error message
upgrade lock intent
What it means
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.
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).
Defensive patterns
Strategy: retry
Validate before calling
// Go: check for an active upgrade intent before long-running operations
intent, err := fmgr.UpgradeLockIntent(ctx)
if err == nil && intent.OwnerID != "" {
return errors.New("another client is upgrading the repository; wait and retry")
} Try / catch
if err != nil && strings.Contains(err.Error(), "upgrade lock intent") {
if isTransientStorageError(err) { return retryWithBackoff(ctx) }
return fmt.Errorf("check upgrade-lock state manually: %w", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- blob configuration
- can only extend the upgrade-time on an existing lock
- can't parse format blob
- cannot set an advance notice an on existing lock
- cannot unset advance notice an on existing lock
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/d14f83b9f0fe985f.
Report an issue: GitHub.
Appendix: source
Thrown at repo/open.go:496
m.RUnlock()
return nil
}
m.RUnlock()
// upgrade the lock and verify again in-case someone else won the race to refresh
m.Lock()
defer m.Unlock()
ltime := fmgr.LoadedTime()
if lastCheckTime.Equal(ltime) {
return nil
}
uli, err := fmgr.UpgradeLockIntent(ctx)
if err != nil {
return errors.Wrap(err, "upgrade lock intent")
}
if err := handleMissingRequiredFeatures(ctx, fmgr, ignoreMissingRequiredFeatures); err != nil {
onFatalError(err)
return err
}
if uli != nil {
// only allow the upgrade owner to perform storage operations
if locked, _ := uli.IsLocked(now()); locked && upgradeOwnerID != uli.OwnerID {
return ErrRepositoryUnavailableDueToUpgradeInProgress
}
}
lastCheckTime = ltime
return nil
}View on GitHub (pinned to 82495e54b5)