duplicati/duplicati · error · UserInformationException

RetentionPolicyParseError

RetentionPolicyParseError

Error message

An error occoured while processing the value of --{0}

What it means

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.

Source

Thrown at Duplicati/Library/Main/Controller.cs:997

            if (m_options.VolumeSize < m_options.Blocksize * 2)
                throw new UserInformationException("The volume size must be at least twice the block size", "VolumeSizeTooSmall");

            //Check validity of retention-policy option value
            try
            {
                foreach (var configEntry in m_options.RetentionPolicy)
                {
                    if (!configEntry.IsKeepAllVersions() && !configEntry.IsUnlimtedTimeframe() &&
                        configEntry.Interval >= configEntry.Timeframe)
                    {
                        throw new Interface.UserInformationException("An interval cannot be bigger than the timeframe it is in", "IntervalCannotBeBiggerThanTimeFrame");
                    }
                }
            }
            catch (Exception e) // simply reading the option value might also result in an exception due to incorrect formatting
            {
                throw new Interface.UserInformationException(string.Format("An error occoured while processing the value of --{0}", "retention-policy"), "RetentionPolicyParseError", e);
            }

            //Keep a list of all supplied options
            var ropts = new Dictionary<string, string>(m_options.RawOptions);

            //Keep a list of all supported options
            var supportedOptions = new Dictionary<string, ICommandLineArgument>();

            //There are a few internal options that are not accessible from outside, and thus not listed
            foreach (var s in Options.InternalOptions)
                supportedOptions[s] = null;

            //Figure out what module options are supported in the current setup
            var moduleOptions = new List<ICommandLineArgument>();
            var disabledModuleOptions = new Dictionary<string, string>();
            var loadedModuleKeys = m_options.LoadedModules.Select(k => k.Key).ToHashSet();

            foreach (var m in DynamicLoader.GenericLoader.Modules)

View on GitHub (pinned to 3f348be3e3)

Solutions

  1. Inspect the InnerException for the precise parse/validation error.
  2. Correct the --retention-policy syntax (comma-separated timeframe[:interval] tokens with valid time units like D/W/M/Y).
  3. Use simpler single retention (e.g. --keep-versions) until the policy string parses.

Example fix

// before: malformed retention-policy
--retention-policy=30 days keep

// after: valid syntax
--retention-policy=30D
Defensive patterns

Strategy: try-catch

Validate before calling

try { var _ = m_options.RetentionPolicy.ToList(); } // force parse early
catch (Exception ex) { throw new ArgumentException("Invalid --retention-policy: " + ex.Message, ex); }

Try / catch

try { controller.BackupAsync(...); }
catch (UserInformationException ex) when (ex.HelpID == "RetentionPolicyParseError")
{ /* inspect ex.InnerException, fix the value, retry */ }

Prevention

When it happens

Trigger: The --retention-policy value is malformed so that enumerating RetentionPolicy throws, OR an inner validation (interval>=timeframe) throws; the surrounding try/catch rewraps it.

Common situations: Typo in the retention-policy string; unsupported time units; missing colon or wrong field count; interval>=timeframe inside a multi-token policy.

Related errors


AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13). Data as JSON: /api/errors/5e84fb3c395a3db4. Report an issue: GitHub.