restic/restic · error

feature flag `s3-restore` is required to use `-o s3.enable-r

Error message

feature flag `s3-restore` is required to use `-o s3.enable-restore=true`

What it means

The S3 backend refuses to start because the option -o s3.enable-restore=true was set while the 's3-restore' feature flag is disabled. Restore-on-read is experimental, so the option is gated behind its feature flag.

Source

Thrown at internal/backend/s3/s3.go:57

type warmupStatus int

const (
	warmupStatusCold warmupStatus = iota
	warmupStatusWarmingUp
	warmupStatusWarm
	warmupStatusLukewarm
)

func NewFactory() location.Factory {
	return location.NewHTTPBackendFactory("s3", ParseConfig, location.NoPassword, Create, Open)
}

func open(cfg Config, rt http.RoundTripper) (*s3, error) {
	debug.Log("open, config %#v", cfg)

	if cfg.EnableRestore && !feature.Flag.Enabled(feature.S3Restore) {
		return nil, fmt.Errorf("feature flag `s3-restore` is required to use `-o s3.enable-restore=true`")
	}

	if cfg.MaxRetries > 0 {
		minio.MaxRetry = int(cfg.MaxRetries)
	}

	creds, err := getCredentials(cfg, rt)
	if err != nil {
		return nil, errors.Wrap(err, "s3.getCredentials")
	}

	options := &minio.Options{
		Creds:     creds,
		Secure:    !cfg.UseHTTP,
		Region:    cfg.Region,
		Transport: rt,
	}

View on GitHub (pinned to a80be1478a)

Solutions

  1. Enable the feature flag together with the option: pass --features s3-restore (or set the RESTIC_FEATURES environment variable to include s3-restore).
  2. Or remove -o s3.enable-restore=true if restore-on-read is not needed.
  3. Run 'restic features' to list flags and their current default state.
  4. Check the changelog: once the feature stabilizes the flag gate is removed.

Example fix

// before
restic -r s3:... backup -o s3.enable-restore=true
// after
restic -r s3:... backup --features s3-restore -o s3.enable-restore=true
Defensive patterns

Strategy: validation

Validate before calling

if cfg.EnableRestore && !feature.Flag.Enabled(feature.S3Restore) {
    return errors.New("enable the s3-restore feature flag (RESTIC_FEATURES=s3-restore) before s3.enable-restore=true")
}

Try / catch

_, err := s3.Create(ctx, cfg, rt)
if err != nil && strings.Contains(err.Error(), "s3-restore") {
    return fmt.Errorf("%w - add --features s3-restore or unset s3.enable-restore", err)
}

Prevention

When it happens

Trigger: Calling restic with -o s3.enable-restore=true (or the equivalent Config.EnableRestore in library code) on a restic version where the s3-restore flag defaults to off.

Common situations: Copy-pasted options from documentation of a newer/older restic; embedding restic and setting EnableRestore without toggling the flag; option carried in a wrapper script after a restic upgrade changed flag defaults.

Related errors


AI-assisted analysis of restic/restic@a80be1478a (2026-08-15). Data as JSON: /api/errors/42a0bc410b7c12ac. Report an issue: GitHub.