{"record":{"id":"46af52b66dbf9d23","repo":"benbjohnson/litestream","slug":"snapshot-retention-must-be-greater-than-0","errorCode":null,"errorMessage":"snapshot retention must be greater than 0","messagePattern":"snapshot retention must be greater than 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":54,"sourceCode":"\t\"github.com/benbjohnson/litestream/webdav\"\n)\n\n// Version is set via -ldflags \"-X main.Version=...\" on release and Makefile\n// builds; otherwise it is resolved from embedded VCS build info at startup.\nvar Version = defaultVersion\n\nfunc init() {\n\tbi, _ := debug.ReadBuildInfo()\n\tVersion = resolveVersion(Version, bi)\n}\n\n// errStop is a terminal error for indicating program should quit.\nvar errStop = errors.New(\"stop\")\n\n// Sentinel errors for configuration validation\nvar (\n\tErrInvalidSnapshotInterval         = errors.New(\"snapshot interval must be greater than 0\")\n\tErrInvalidSnapshotRetention        = errors.New(\"snapshot retention must be greater than 0\")\n\tErrInvalidCompactionInterval       = errors.New(\"compaction interval must be greater than 0\")\n\tErrInvalidSyncInterval             = errors.New(\"sync interval must be greater than 0\")\n\tErrInvalidL0Retention              = errors.New(\"l0 retention must not be negative\")\n\tErrInvalidL0RetentionCheckInterval = errors.New(\"l0 retention check interval must be greater than 0\")\n\tErrInvalidShutdownSyncTimeout      = errors.New(\"shutdown-sync-timeout must be >= 0\")\n\tErrInvalidShutdownSyncInterval     = errors.New(\"shutdown sync interval must be greater than 0\")\n\tErrInvalidHeartbeatURL             = errors.New(\"heartbeat URL must be a valid HTTP or HTTPS URL\")\n\tErrInvalidHeartbeatInterval        = errors.New(\"heartbeat interval must be at least 1 minute\")\n\tErrConfigFileNotFound              = errors.New(\"config file not found\")\n)\n\n// ConfigValidationError wraps a validation error with additional context\ntype ConfigValidationError struct {\n\tErr   error\n\tField string\n\tValue interface{}\n}\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L36-L72","documentation":"Sentinel error ErrInvalidSnapshotRetention is returned by Config.Validate when a configured snapshot retention is present but <= 0. Snapshot retention controls how long snapshots are kept, so a non-positive value is invalid and rejected during config validation. It is wrapped in ConfigValidationError identifying the field (snapshot.retention or dbs[<id>].snapshot.retention) and value.","triggerScenarios":"Setting snapshot.retention <= 0 at the top level or inside a dbs[] snapshot block; loading a config where retention was computed as 0 (e.g. empty variable or unit typo like \"0h\").","commonSituations":"Attempting to 'disable' retention by setting it to 0 (use retention disabling options instead); mistyping a duration so it parses to zero; generated configs with missing defaults.","solutions":["Set snapshot.retention to a positive duration (e.g. \"720h\" for 30 days) or remove the key to use the default.","If you intend to rely on cloud lifecycle policies instead, configure that at the storage provider level and keep a valid positive retention here.","Fix the templating/source that produced the zero value."],"exampleFix":"# before\nsnapshot:\n  retention: 0\n# after\nsnapshot:\n  retention: 720h","handlingStrategy":"validation","validationCode":"func validSnapshotRetention(d time.Duration) bool { return d > 0 }\nif cfg.Snapshot != nil && cfg.Snapshot.Retention != nil && *cfg.Snapshot.Retention <= 0 {\n    return errors.New(\"snapshot.retention must be > 0\")\n}","typeGuard":null,"tryCatchPattern":"if err := cfg.Validate(); err != nil {\n    var ve *main.ConfigValidationError\n    if errors.As(err, &ve) && errors.Is(ve.Err, main.ErrInvalidSnapshotRetention) {\n        return fmt.Errorf(\"retention %v at %s is invalid\", ve.Value, ve.Field)\n    }\n    return err\n}","preventionTips":["Use positive duration literals for retention; do not try to disable retention with 0.","Run config validation in CI for generated litestream configs.","Document defaults so users omit keys instead of setting them to zero."],"tags":["go","configuration","validation","retention"],"backgroundTag":"invalid-config-value","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}