Release: 2.1.0.121 (Canary) 2025-07-07

2.1.0.121_canary_2025-07-07

This release is a canary release intended to be used for testing.

EDIT: A bug in this version will prevent it from registering notifications from the UI, please use a later version.

Major changes in this version

This version introduces a new SQLite library, a new VSS provider, and some minor bugfixes.

SQLite update

This version has changed the SQLite library from the previous System.Data.SQLite library to using Microsoft.Data.Sqlite.
This update was quite invasive, as the new SQLite library does not support positional arguments in SQL queries, which was used extensively in the Duplicati codebase.
With the update we see measurable speedups across all queries, and we are producing an article that describes our findings.
The update also bumps the SQLite library to use the latest available version and makes all SQLite queries async and cancelable, making the stop commands more responsive.

New VSS provider supprt

The AlphaVSS library that is used for creating VSS snapshots is no longer being maintained.
This version now defaults to using the Vanara API layer to call the Windows VSS API and create snapshots.
Like before, this still requires the VC++ Redist to be installed.
For now, it is still possible to use AlphaVSS by setting --snapshot-provider=AlphaVSS.
Note that neither works on ARM64 as Windows is lacking libraries and tools for native ARM64 snapshots, only --snapshot-provider=WMIC works on ARM64.

Bugfixing for ngclient

A number of reported compatibility issues with ngax has been fixed in this version.

Detailed list of changes:

  • Commandline UI expands environment variables
  • The file:// backend is no longer throttle exempt by default
  • Fixed issue with TrayIcon not outputting help text in all cases
  • No longer retains SeBackupPrivilege after testing for permissions
  • Refresh token lifetime can now be configured
  • Fixed multiple issues with kill signals not stopping the process
  • Secret provider now correctly applied for all TrayIcon arguments
  • Updated SQLite library to use Microsoft.Data.Sqlite packages instead
  • Default VSS provider is now Vanara
  • Hide options that are not supported on the current OS
  • Fixed backup schedule order after multiple missed backups
  • Fixed an issue with Google Drive backend not creating folders
  • Updated all localization, thanks to all translators

Ngclient changes:

  • Fixed issue with -- option prefixes not being matched
  • Updated all localization, thanks to all translators
  • Fixed issue with en-GB not using 24h time format
  • Fixed issue with editor for GCS not having a path field
  • Fixed issue with editor for B2 introducing extra / characters
  • Fixed supporting -s postfix for backends for backwards compatibility
  • Fixed case-insensitive support for boolean and enumeration options
  • Custom arguments is now a two-line input

No GUI when launching. No warning. When I run Duplicati.GUI.TrayIcon.exe via CMD, this comes up:

No database encryption key was found. The database will be stored unencrypted. Supply an encryption key via the environment variable SETTINGS_ENCRYPTION_KEY or disable database encryption with the option --disable-db-encryption
Crash!
Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: A serious error has occurred in Duplicati: System.InvalidOperationException: Value must be set.
   at Microsoft.Data.Sqlite.SqliteParameter.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteParameterCollection.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Action`1 insertPrep, Action`2 insert)
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Boolean updateExisting)
   at Duplicati.Server.Database.Connection.RegisterNotification(NotificationType type, String title, String message, Exception ex, String backupid, String action, String logid, String messageid, String logtag, Func`3 conflicthandler)
   at Duplicati.Server.Program.EmitWarningsForConfigurationIssues(Connection connection, IApplicationSettings applicationSettings, Dictionary`2 commandlineOptions)
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
 ---> System.InvalidOperationException: Value must be set.
   at Microsoft.Data.Sqlite.SqliteParameter.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteParameterCollection.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Action`1 insertPrep, Action`2 insert)
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Boolean updateExisting)
   at Duplicati.Server.Database.Connection.RegisterNotification(NotificationType type, String title, String message, Exception ex, String backupid, String action, String logid, String messageid, String logtag, Func`3 conflicthandler)
   at Duplicati.Server.Program.EmitWarningsForConfigurationIssues(Connection connection, IApplicationSettings applicationSettings, Dictionary`2 commandlineOptions)
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object _)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(IApplicationSettings applicationSettings, String[] args)
   at Duplicati.GUI.TrayIcon.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.Net8.Program.<>c__DisplayClass0_0.<Main>b__0()
   at Duplicati.Library.Crashlog.CrashlogHelper.WrapWithCrashLog[T](Func`1 method)
Unhandled exception. Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Произошел серьезный сбой в Duplicati: System.InvalidOperationException: Value must be set.
   at Microsoft.Data.Sqlite.SqliteParameter.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteParameterCollection.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Action`1 insertPrep, Action`2 insert)
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Boolean updateExisting)
   at Duplicati.Server.Database.Connection.RegisterNotification(NotificationType type, String title, String message, Exception ex, String backupid, String action, String logid, String messageid, String logtag, Func`3 conflicthandler)
   at Duplicati.Server.Program.EmitWarningsForConfigurationIssues(Connection connection, IApplicationSettings applicationSettings, Dictionary`2 commandlineOptions)
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
 ---> System.InvalidOperationException: Value must be set.
   at Microsoft.Data.Sqlite.SqliteParameter.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteParameterCollection.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Action`1 insertPrep, Action`2 insert)
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Boolean updateExisting)
   at Duplicati.Server.Database.Connection.RegisterNotification(NotificationType type, String title, String message, Exception ex, String backupid, String action, String logid, String messageid, String logtag, Func`3 conflicthandler)
   at Duplicati.Server.Program.EmitWarningsForConfigurationIssues(Connection connection, IApplicationSettings applicationSettings, Dictionary`2 commandlineOptions)
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object _)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(IApplicationSettings applicationSettings, String[] args)
   at Duplicati.GUI.TrayIcon.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.Net8.Program.<>c__DisplayClass0_0.<Main>b__0()
   at Duplicati.Library.Crashlog.CrashlogHelper.WrapWithCrashLog[T](Func`1 method)
   at Duplicati.GUI.TrayIcon.Net8.Program.Main(String[] args)

Same on linux mint.
Downgrading back to v2.1.0.120_canary_2025-06-24 fixes.

❯ duplicati --webservice-port=8200
No database encryption key was found. The database will be stored unencrypted. Supply an encryption key via the environment variable SETTINGS_ENCRYPTION_KEY or disable database encryption with the option --disable-db-encryption
Crash! 
Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: A serious error occurred in Duplicati: System.InvalidOperationException: Value must be set.
   at Microsoft.Data.Sqlite.SqliteParameter.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteParameterCollection.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Action`1 insertPrep, Action`2 insert)
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Boolean updateExisting)
   at Duplicati.Server.Database.Connection.RegisterNotification(NotificationType type, String title, String message, Exception ex, String backupid, String action, String logid, String messageid, String logtag, Func`3 conflicthandler)
   at Duplicati.Server.Program.EmitWarningsForConfigurationIssues(Connection connection, IApplicationSettings applicationSettings, Dictionary`2 commandlineOptions)
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
 ---> System.InvalidOperationException: Value must be set.
   at Microsoft.Data.Sqlite.SqliteParameter.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteParameterCollection.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Action`1 insertPrep, Action`2 insert)
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Boolean updateExisting)
   at Duplicati.Server.Database.Connection.RegisterNotification(NotificationType type, String title, String message, Exception ex, String backupid, String action, String logid, String messageid, String logtag, Func`3 conflicthandler)
   at Duplicati.Server.Program.EmitWarningsForConfigurationIssues(Connection connection, IApplicationSettings applicationSettings, Dictionary`2 commandlineOptions)
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object _)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(IApplicationSettings applicationSettings, String[] args)
   at Duplicati.GUI.TrayIcon.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.Net8.Program.<>c__DisplayClass0_0.<Main>b__0()
   at Duplicati.Library.Crashlog.CrashlogHelper.WrapWithCrashLog[T](Func`1 method)
Unhandled exception. Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: A serious error occurred in Duplicati: System.InvalidOperationException: Value must be set.
   at Microsoft.Data.Sqlite.SqliteParameter.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteParameterCollection.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Action`1 insertPrep, Action`2 insert)
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Boolean updateExisting)
   at Duplicati.Server.Database.Connection.RegisterNotification(NotificationType type, String title, String message, Exception ex, String backupid, String action, String logid, String messageid, String logtag, Func`3 conflicthandler)
   at Duplicati.Server.Program.EmitWarningsForConfigurationIssues(Connection connection, IApplicationSettings applicationSettings, Dictionary`2 commandlineOptions)
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
 ---> System.InvalidOperationException: Value must be set.
   at Microsoft.Data.Sqlite.SqliteParameter.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteParameterCollection.Bind(sqlite3_stmt stmt, sqlite3 handle)
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery()
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Action`1 insertPrep, Action`2 insert)
   at Duplicati.Server.Database.Connection.OverwriteAndUpdateDb[T](IDbTransaction transaction, Action`1 deletePrep, IEnumerable`1 values, Boolean updateExisting)
   at Duplicati.Server.Database.Connection.RegisterNotification(NotificationType type, String title, String message, Exception ex, String backupid, String action, String logid, String messageid, String logtag, Func`3 conflicthandler)
   at Duplicati.Server.Program.EmitWarningsForConfigurationIssues(Connection connection, IApplicationSettings applicationSettings, Dictionary`2 commandlineOptions)
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(IApplicationSettings applicationSettings, String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object _)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(IApplicationSettings applicationSettings, String[] args)
   at Duplicati.GUI.TrayIcon.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.Net8.Program.<>c__DisplayClass0_0.<Main>b__0()
   at Duplicati.Library.Crashlog.CrashlogHelper.WrapWithCrashLog[T](Func`1 method)
   at Duplicati.GUI.TrayIcon.Net8.Program.Main(String[] args)
[1]    2446522 IOT instruction (core dumped)  duplicati --webservice-port=8200

Thanks for reporting. I am looking into it. EDIT: I can reproduce.

1 Like

PR ready that fixes it:

Testing this for possible inclusion:

1 Like

Many new UI Destination fields usually (but not always) turn a space into a %20.
This can happen during Import or just typing. I found this on Folder path first, so:

import percent-encodes spaces in Path on server #320

It’s also on Server and Bucket. Others such as Username and Password are OK.
This makes ngclient hard to use. One can’t even paste in Path for a workaround.

Oddly Test destination works (didn’t it get improved?), but Verify sees no files

Edit target URL and changing %20 into spaces also doesn’t work. %20 returns.

Thanks for reporting. I think we need to fix it again for the server+path pairs