{"record":{"id":"5e84fb3c395a3db4","repo":"duplicati/duplicati","slug":"retentionpolicyparseerror","errorCode":"RetentionPolicyParseError","errorMessage":"An error occoured while processing the value of --{0}","messagePattern":"An error occoured while processing the value of --(.+?)","errorType":"exception","errorClass":"UserInformationException","httpStatus":null,"severity":"error","filePath":"Duplicati/Library/Main/Controller.cs","lineNumber":997,"sourceCode":"\n            if (m_options.VolumeSize < m_options.Blocksize * 2)\n                throw new UserInformationException(\"The volume size must be at least twice the block size\", \"VolumeSizeTooSmall\");\n\n            //Check validity of retention-policy option value\n            try\n            {\n                foreach (var configEntry in m_options.RetentionPolicy)\n                {\n                    if (!configEntry.IsKeepAllVersions() && !configEntry.IsUnlimtedTimeframe() &&\n                        configEntry.Interval >= configEntry.Timeframe)\n                    {\n                        throw new Interface.UserInformationException(\"An interval cannot be bigger than the timeframe it is in\", \"IntervalCannotBeBiggerThanTimeFrame\");\n                    }\n                }\n            }\n            catch (Exception e) // simply reading the option value might also result in an exception due to incorrect formatting\n            {\n                throw new Interface.UserInformationException(string.Format(\"An error occoured while processing the value of --{0}\", \"retention-policy\"), \"RetentionPolicyParseError\", e);\n            }\n\n            //Keep a list of all supplied options\n            var ropts = new Dictionary<string, string>(m_options.RawOptions);\n\n            //Keep a list of all supported options\n            var supportedOptions = new Dictionary<string, ICommandLineArgument>();\n\n            //There are a few internal options that are not accessible from outside, and thus not listed\n            foreach (var s in Options.InternalOptions)\n                supportedOptions[s] = null;\n\n            //Figure out what module options are supported in the current setup\n            var moduleOptions = new List<ICommandLineArgument>();\n            var disabledModuleOptions = new Dictionary<string, string>();\n            var loadedModuleKeys = m_options.LoadedModules.Select(k => k.Key).ToHashSet();\n\n            foreach (var m in DynamicLoader.GenericLoader.Modules)","sourceCodeStart":979,"sourceCodeEnd":1015,"githubUrl":"https://github.com/duplicati/duplicati/blob/3f348be3e33f5d72d414e3ad55839c2ba34dda67/Duplicati/Library/Main/Controller.cs#L979-L1015","documentation":"Thrown by Controller.ValidateOptions as the catch-all wrapper around retention-policy parsing: any exception raised while enumerating/reading m_options.RetentionPolicy (including the IntervalCannotBeBiggerThanTimeFrame throw and malformed value parsing) is rewrapped with this message and the code RetentionPolicyParseError, preserving the original as InnerException.","triggerScenarios":"The --retention-policy value is malformed so that enumerating RetentionPolicy throws, OR an inner validation (interval>=timeframe) throws; the surrounding try/catch rewraps it.","commonSituations":"Typo in the retention-policy string; unsupported time units; missing colon or wrong field count; interval>=timeframe inside a multi-token policy.","solutions":["Inspect the InnerException for the precise parse/validation error.","Correct the --retention-policy syntax (comma-separated timeframe[:interval] tokens with valid time units like D/W/M/Y).","Use simpler single retention (e.g. --keep-versions) until the policy string parses."],"exampleFix":"// before: malformed retention-policy\n--retention-policy=30 days keep\n\n// after: valid syntax\n--retention-policy=30D","handlingStrategy":"try-catch","validationCode":"try { var _ = m_options.RetentionPolicy.ToList(); } // force parse early\ncatch (Exception ex) { throw new ArgumentException(\"Invalid --retention-policy: \" + ex.Message, ex); }","typeGuard":null,"tryCatchPattern":"try { controller.BackupAsync(...); }\ncatch (UserInformationException ex) when (ex.HelpID == \"RetentionPolicyParseError\")\n{ /* inspect ex.InnerException, fix the value, retry */ }","preventionTips":["Parse retention-policy eagerly at config-load time to fail fast.","Surface InnerException to users for actionable messages."],"tags":["configuration","retention","parsing","validation"],"backgroundTag":null,"analyzedSha":"3f348be3e33f5d72d414e3ad55839c2ba34dda67","analyzedAt":"2026-08-13T16:48:27.008Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}