kopia/kopia · error
please set env variable to use this feature
Error message
please set %q env variable to use this feature
What it means
The `repository upgrade` sub-command is experimental and guarded: its kingpin Validate hook requires the environment variable named by upgradeLockFeatureEnv (KOPIA_ENABLE_EXPERIMENTAL_UPGRADE_LOCK) to be set to a non-empty value. Without it, the command refuses to run with this error.
Solutions
- Set the required env variable before running: `export KOPIA_ENABLE_EXPERIMENTAL_UPGRADE_LOCK=on` (any non-empty value).
- Re-run the upgrade command in the same shell/session so the variable is visible.
- In CI, add the variable to the job's environment/secrets configuration.
- Read the repository-upgrade docs to confirm the flow before enabling the experimental feature.
Example fix
// before kopia repository upgrade begin ... // error: please set "KOPIA_ENABLE_EXPERIMENTAL_UPGRADE_LOCK" env variable to use this feature // after export KOPIA_ENABLE_EXPERIMENTAL_UPGRADE_LOCK=on kopia repository upgrade begin ...
Defensive patterns
Strategy: validation
Validate before calling
// fail fast in scripts if the experimental-upgrade gate is missing
if os.Getenv("KOPIA_ENABLE_EXPERIMENTAL_UPGRADE_LOCK") == "" {
return errors.New("repository upgrade requires KOPIA_ENABLE_EXPERIMENTAL_UPGRADE_LOCK to be set")
} Try / catch
if err := upgradeCmd.Run(); err != nil && strings.Contains(err.Error(), "env variable to use this feature") {
fmt.Fprintln(os.Stderr, "export KOPIA_ENABLE_EXPERIMENTAL_UPGRADE_LOCK=on before running repository upgrade")
os.Exit(1)
} Prevention
- Export the env variable in the same shell/session (or CI job env) that runs the upgrade.
- Document the experimental gate in runbooks for repository upgrades.
- Verify with `echo $KOPIA_ENABLE_EXPERIMENTAL_UPGRADE_LOCK` before the upgrade step.
- Read the upgrade documentation; the feature is intentionally hidden and gated.
When it happens
Trigger: Invoking `kopia repository upgrade ...` (or its begin/resume sub-commands) when the upgrade-lock feature env variable is unset or empty.
Common situations: Operators upgrading a direct-write (filesystem/rclone) repository who are unaware the new upgrade flow is feature-gated; CI scripts that worked before the guard was introduced; env var set in the wrong shell/session or with an empty value.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- failed to rollback the upgrade
- minimum required io-drain-timeout is
- repository will remain locked until index differences are…
- a snapshot time is needed to use a path as source
- aborted
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/e5234efcf49dcda1.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command_repository_upgrade.go:54
experimentalWarning = `WARNING: The upgrade command is an EXPERIMENTAL feature. Please DO NOT use it, it may corrupt your repository and cause data loss.
You will need to set the env variable KOPIA_UPGRADE_LOCK_ENABLED in order to use this feature.
`
upgradeLockFeatureEnv = "KOPIA_UPGRADE_LOCK_ENABLED"
maxPermittedClockDriftDefault = 5 * time.Minute
)
const (
commitModeAlwaysCommit = "always"
commitModeNeverCommit = "never"
)
func (c *commandRepositoryUpgrade) setup(svc advancedAppServices, parent commandParent) {
// override the parent, the upgrade sub-command becomes the new parent here-onwards
parent = parent.Command("upgrade", "Upgrade repository format.\n\n"+warningColor.Sprint(experimentalWarning)).Hidden().
Validate(func(_ *kingpin.CmdClause) error {
if v := os.Getenv(c.svc.EnvName(upgradeLockFeatureEnv)); v == "" {
return errors.Errorf("please set %q env variable to use this feature", upgradeLockFeatureEnv)
}
return nil
})
beginCmd := parent.Command("begin", "Begin upgrade.")
beginCmd.Flag("io-drain-timeout", "Max time it should take all other Kopia clients to drop repository connections").Default(format.DefaultRepositoryBlobCacheDuration.String()).DurationVar(&c.ioDrainTimeout)
beginCmd.Flag("allow-unsafe-upgrade", "Force using an unsafe io-drain-timeout for the upgrade lock").Default(falseStr).Hidden().BoolVar(&c.allowUnsafeUpgradeTimings)
beginCmd.Flag("status-poll-interval", "An advisory polling interval to check for the status of upgrade").Default("60s").DurationVar(&c.statusPollInterval)
beginCmd.Flag("max-permitted-clock-drift", "The maximum drift between repository and client clocks").Default(maxPermittedClockDriftDefault.String()).DurationVar(&c.maxPermittedClockDrift)
beginCmd.Flag("lock-only", "Advertise the upgrade lock and exit without actually performing the drain or upgrade").Default(falseStr).Hidden().BoolVar(&c.lockOnly) // this is used by tests
beginCmd.Flag("commit-mode", "Change behavior of commit. When not set, commit on validation success. 'always': always commit. 'never': always exit before commit.").Hidden().EnumVar(&c.commitMode, commitModeAlwaysCommit, commitModeNeverCommit)
// upgrade phases
// Set the upgrade lock intent.
beginCmd.Action(svc.directRepositoryWriteAction(c.runPhase(c.setLockIntent)))
// If requested then drain all the clients otherwise stop here.View on GitHub (pinned to 82495e54b5)