kopia/kopia · error
no upgrade in progress
Error message
no upgrade in progress
What it means
CommitUpgrade returns this ad-hoc error when finalizing a repository format upgrade but the repository configuration carries no UpgradeLock, meaning no upgrade was ever initiated. Committing an upgrade requires an in-progress lock; without one the operation is invalid.
Solutions
- Call SetUpgradeLockIntent first and only then CommitUpgrade
- Verify the lock is present (ReadUpgradeLock) before committing
- Ensure all clients share the same blob storage so the lock is visible
- Fix orchestration so commit runs exactly once, after the drain phase
Example fix
// before
if err := fm.CommitUpgrade(ctx); err != nil { ... }
// after
lock, err := fm.ReadUpgradeLock(ctx)
if err != nil || lock == nil {
return errors.New("upgrade lock must be set before committing upgrade")
}
if err := fm.CommitUpgrade(ctx); err != nil { ... } Defensive patterns
Strategy: try-catch
Validate before calling
lock, err := fm.ReadUpgradeLock(ctx)
if err != nil { return err }
if lock == nil {
return errors.New("cannot commit: no upgrade lock present")
} Try / catch
if err := fm.CommitUpgrade(ctx); err != nil {
if strings.Contains(err.Error(), "no upgrade in progress") {
log.Info("nothing to commit")
return nil
}
return err
} Prevention
- Always pair CommitUpgrade with a preceding SetUpgradeLockIntent in the same workflow
- Make commit/rollback steps idempotent in scripts
- Refresh repository config from shared storage before committing
- Run only one coordinator process for the upgrade at a time
When it happens
Trigger: Calling FormatManager().CommitUpgrade(ctx) when repoConfig.UpgradeLock is nil — i.e. without a prior successful SetUpgradeLockIntent, or after the lock was already removed.
Common situations: Calling CommitUpgrade out of order in scripts or tooling; invoking it on a second connection where the lock set by another process is not visible in the cached config; retrying commit after a previous successful commit already cleared the lock.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- can only extend the upgrade-time on an existing lock
- cannot set an advance notice an on existing lock
- cannot unset advance notice an on existing lock
- io-drain-timeout is required to be set for the upgrade lock
- no owner-id set, it is required to set a unique owner-id
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/5efdb984111349d8.
Report an issue: GitHub.
Appendix: source
Thrown at repo/format/upgrade_lock.go:107
ctx,
LegacyIndexPoisonBlobID,
gather.FromSlice([]byte("The format of this repository has been upgraded and cannot be read by old clients")),
blob.PutOptions{})
}
// CommitUpgrade removes the upgrade lock from the from the repository format
// blob. This in-effect commits the new repository format to the repository and
// resumes all access to the repository.
func (m *Manager) CommitUpgrade(ctx context.Context) error {
if err := m.maybeRefreshNotLocked(ctx); err != nil {
return err
}
m.mu.Lock()
defer m.mu.Unlock()
if m.repoConfig.UpgradeLock == nil {
return errors.New("no upgrade in progress")
}
// poison V0 index so that old readers won't be able to open it.
if err := WriteLegacyIndexPoisonBlob(ctx, m.blobs); err != nil {
log(ctx).Errorf("unable to write legacy index poison blob: %v", err)
}
// restore the old format version
m.repoConfig.UpgradeLock = nil
return m.updateRepoConfigLocked(ctx)
}
// RollbackUpgrade removes the upgrade lock while also restoring the
// format-blob's original version. This method does not restore the original
// repository data format and neither does it validate against any repository
// changes. Rolling back the repository format is currently not supported and
// hence using this API could render the repository corrupted and unreadable byView on GitHub (pinned to 82495e54b5)