1 Backup every day keep for 365 Days only had the last backup available to restore

I had the settings as follows in the screen shots. And assumed with these settings that I would have a daily backup available for restore for 365 days. Backing up to Azure Storage Account.

But went to restore a backup from a few days ago and found that I only had one version (the previous days backup) available for restore.


I have since changed to “Custom backup retention” with 7D:1D,4W:1W,12M:1M settings and am now seeing multiple versions available.

My question is: Did I have my initial settings incorrect or have I found a bug in the software?
I am currently running version

Good question. I’m not really sure what happens when you have retention set to “365 custom”. If it was set to “365 days” then it should have worked as you expected. I don’t know what “custom” does in this context, and why it’s even an option in that dropdown.

I’ll try to do some testing when I have a moment.

Not to detract from that, but as a guess the custom might be bring-your-own-(many)-units.

help time says

  Y, M, D, W, h, m, s --> Relative date and time: year, month, day, week,
  hour, minute, second. Example: 2M10D5h is now + 2 months + 10 days + 5

We use this sort of addition with custom retention rules, e.g. 23h30m to fudge a little from 1D.
If you look at Export As Command-line you see the unit added per specific dropdown unit.
Using custom doesn’t do this, so I suspect the ParseTimeInterval code never adds value:

This might be incorrect setting plus JavaScript and C# code that missed validation then lost it.
There’s some level of JavaScript validation, e.g. if I ask for 365X it pops up a message saying


If I bypass the GUI and put it on CLI:

System.Exception: Unparsed data: 365X
   at Duplicati.Library.Utility.Timeparser.ParseTimeInterval(String datestring, DateTime offset, Boolean negate)
   at Duplicati.Library.Utility.Timeparser.ParseTimeSpan(String datestring)
   at Duplicati.Library.Main.Options.get_KeepTime()
   at Duplicati.Library.Main.Controller.ValidateOptions()
   at Duplicati.Library.Main.Controller.SetupCommonOptions(ISetCommonOptions result, String[]& paths, IFilter& filter)
   at Duplicati.Library.Main.Controller.RunAction[T](T result, String[]& paths, IFilter& filter, Action`1 method)
   at Duplicati.Library.Main.Controller.Backup(String[] inputsources, IFilter filter)
   at Duplicati.CommandLine.Commands.Backup(TextWriter outwriter, Action`1 setup, List`1 args, Dictionary`2 options, IFilter filter)
   at Duplicati.CommandLine.Program.ParseCommandLine(TextWriter outwriter, Action`1 setup, Boolean& verboseErrors, String[] args)
   at Duplicati.CommandLine.Program.RunCommandLine(TextWriter outwriter, TextWriter errwriter, Action`1 setup, String[] args)
1 Like

Yeah I thought about that and was going to ask the OP to “export as command line” so we could see if a custom unit was used (maybe “s” or “m”). But then I saw they had already changed their retention config, so I guess we’ll never know.

I was able to type “365 s” in the backup retention field and it seemed to accept it, as confirmed by exporting as command line:

Sure enough when I ran a backup it deleted everything except the most recent one, as other backups were more than 365 seconds ago.

asking for 365 custom is equivalent to 365 seconds IMO

1 Like

The early catch of this form looks plausible (I’m not a C# dev though). Thanks for noticing that one.
If someone really wanted to test, they could probably use as many seconds as they like as a value.
A faster test might be to try the same stunt elsewhere, e.g. the schedule interval also takes custom.

I don’t think so… I tested 365 custom and it didn’t delete backup versions that were over 365 seconds old.

Never mind… I think you’re right! I just tested again and it DOES behave like it’s seconds when no unit is specified. Not sure how I messed up my earlier test.

checking the documentation, the ‘timespan’ idea is used but not made explicit.

There are quite the corner cases in the code: an integer = seconds, ‘now’ (or ‘Now’, ‘NOW’…) means what it says, a human formatted date (according to locale), a time serial (I’m have not tried to look up what it means for a C# software), and finally the Duplicity format strings such as 1W2D5h42m.
There is even a 1% default tolerance that one can disable.

I “might” have tried some of the date or now based versions in --time option on restore, with little luck.
Below might actually be useful if it means the nearest backup before a time. Wording confuses me…

Restore files that are older than the specified time.

Kenneth wanted to port duplicity from Linux to Windows. is what led into Duplicati and then Duplicati 2. Somewhat far removed now (and I haven’t used Duplicity), but possibly some things have carried over.