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

  1. Check the wrapped cause for the concrete read failure.
  2. Verify storage connectivity/credentials and let the monitor retry on the next tick.
  3. If another client holds an upgrade lock, wait for the upgrade to finish (kopia repository status shows upgrade intent).
  4. 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

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


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)