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
- 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.
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
- Parse retention-policy eagerly at config-load time to fail fast.
- Surface InnerException to users for actionable messages.
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
- MultipleRetentionOptionsNotSupported
- IntervalCannotBeBiggerThanTimeFrame
- B2InvalidPageSize
- DrimeCloudInvalidPageSize
- UrlOptionMissing
AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13).
Data as JSON: /api/errors/5e84fb3c395a3db4.
Report an issue: GitHub.