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
- Enable the feature flag together with the option: pass --features s3-restore (or set the RESTIC_FEATURES environment variable to include s3-restore).
- Or remove -o s3.enable-restore=true if restore-on-read is not needed.
- Run 'restic features' to list flags and their current default state.
- 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
- Check 'restic features' output before using experimental S3 options.
- Keep options and feature flags versioned together in the backup script.
- Re-read the changelog on restic upgrades for flag graduation/removal.
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
- bad bucket-lookup style %q must be "auto", "path" or "dns"
- name for exclusion tagfile is empty
- no name for exclusion tagfile provided
- negative values not allowed, use 'unlimited' instead
- invalid path (no path components)
AI-assisted analysis of restic/restic@a80be1478a (2026-08-15).
Data as JSON: /api/errors/42a0bc410b7c12ac.
Report an issue: GitHub.