Setup Server DB encryption with Windows Credential Manager

I would like to handle following message at startup:

27. Febr. 2025 10:02: 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

Looking at several posts in the forum, the message is about the server DB encryption key missing. I don’t want to store the passphrase for that in plain text and thus thought about using Windows credential manager. As I have never actively used that tool before, could you confirm how to set up the key properly?
My assumptions are based on following posts and documentation resources:
Securing the database, Using the secret provider, Announcement of secrets with example

What I think I should do:
Windows Credentials → Generic Credentials → Add a generic credential → Enter info for fields internet or network address, Username, Password:

internet or network address: localhost:8200 (host name of the running duplicati application)
Username: duplicati-server (username to be referred to in argument --settings-encryption-key)
Password: <password to be set and subsequently used>

From then on, always start Duplicati using command line arguments and referring to the stored credentials:

"C:\Program Files\Duplicati 2\Duplicati.GUI.TrayIcon.exe" --secret-provider=wincred:// --settings-encryption-key=$duplicati-server

Is this how it works? Specifically, does Duplicati use the --settings-encryption-key-value as mapping for the Username in credentials manager or for the internet or network address field?

Thanks for clarifying!

From what I recall the “Internet or network address” is mislabelled in the Windows UI as it is actually called “TargetName” in the Windows API and can be any string. This is the name that you refer to with the secret manager.

Yes, that is how it works.

The translation will look for $duplicati-server and check the Windows Credentials for an entry with the “internet or network address” value “duplicati-server”, and then replace it with the password. The username is not currently used by Duplicati.

If any of the values cannot be resolved, the start will fail.

For a slightly better testing experience, you can use the commandline and then:

Duplicati.CommandLine.SecretTool.exe test wincred:// duplicati-server

The output will tell you if the lookup works.

1 Like

Perfect, many thanks, that already answered my follow-up questions about verifying whether the passphrase could be resolved!

I managed to configure it appropriately and can see that the Duplicati-server.sqlite now features some encrypted columns (with enc: prefix in the value) in the tables Backup and Option.

Just for your information: The wrong configuration I previously proposed did not raise any visible error in the server logs UI (About → Log → Live → Verbose) and the warning about the missing database encryption key did no more occur (2.1.0.2_beta_2024-11-29). The server just started normally when running Duplicati.GUI.TrayIcon.exe. However, I did not test starting a backup, maybe the failure would occur later?

This tool indeed reported that the previous configuration was wrong (KeyNotFoundException raised) and that the corrected one works as intended.

That sounds bad. That would imply that it is using the literal string $duplicati-server as the encryption key. The database is checked on startup, so this is where it will fail.

However, if you managed to get it started with a wrong key, it should be encrypted, and fixing the input should then fail (as the key has changed). Did that happen?

I even had created a copy of the Duplicati-server.sqlite before moving on from the “wrong” to the “correct” configuration, but I’m afraid I already deleted it after seeing the encryption being successfully applied. I think (but am not sure and can no more verify) that the database tables did not have encrypted column values at the time of the “wrong” configuration being active.
I did not see any error message in the Server logs after correcting the configuration and a test backup also went successfully.

If I can help you reproduce that behavior anyhow (e.g., by removing encryption and then testing the “wrong” configuration again), let me know.
One idea could be that the command line parameters were ignored for some reason at the time of the “wrong” configuration (even though I would expect the warning message of the missing database encryption key to appear in the verbose Server log then). I use different ways to start the Duplicati.GUI.TrayIcon.exe (registry entry for auto start vs shortcut for manual start) but both have the command line parameters set identically and in the current state, using either one of both options leads to a successful start of Duplicati, so I would not suspect an issue in any of them.

Note that I updated Duplicati to 2.1.0.4_stable_2025-01-31 after the successful encryption, so the setup might have changed a little for any subsequent tests.

That would at least make it less problematic.
But I agree, it should make a log message if there is no encryption applied.

I am using Windows and added a credential as follows:

Internet or network address: duplicati-server
User name: duplicati-server
Password: ******

Then I started Duplicati using this command line:

"C:\Program Files\Duplicati 2\Duplicati.GUI.TrayIcon.exe" --secret-provider=wincred:// --settings-encryption-key=$duplicati-server

Then I close the tray icon and waited until the process disappeared from the Task Manager. If I try to start Duplicati using the password I created in the Credential Manager, it says I am using the wrong password. Instead of using my password, the database was encrypted using the “$duplicati-server” literal. I am using the latest stable version 2.1.0.5.

Do you have any suggestions to solve this issue?

Can you try the secret tool:

Duplicati.CommandLine.SecretTool.exe wincred:// duplicati-server

This gives an error if it somehow fails to locate the key, which is the first step.

So you mean the password is literally $duplicati-server ?
How did you verify this? If not verified, you can try (no provider specified):

"C:\Program Files\Duplicati 2\Duplicati.GUI.TrayIcon.exe" --settings-encryption-key=$duplicati-server

If the database was previously encrypted, you can decrypt it with the correct key and:

"C:\Program Files\Duplicati 2\Duplicati.GUI.TrayIcon.exe" --settings-encryption-key=<real-key> --disable-db-encryption

Can you try the secret tool:

Duplicati.CommandLine.SecretTool.exe wincred:// duplicati-server

Here is the result:

C:\Program Files\Duplicati 2>Duplicati.CommandLine.SecretTool.exe test wincred:// duplicati-server
NOTE: Secret values are not displayed for security reasons
Secrets:
- duplicati-server: Found!

So you mean the password is literally $duplicati-server ?

Yes. My password in Credential Manager is:
testtest

If I set --settings-encryption-key to $duplicati-server, it works.

C:\Program Files\Duplicati 2>Duplicati.GUI.TrayIcon.exe --settings-encryption-key=$duplicati-server

C:\Program Files\Duplicati 2>Server has started and is listening on port 8200

But if I set --settings-encryption-key to testtest or “testtest” or even $DuPliCaTi-SerVer, I get the following error:

C:\Program Files\Duplicati 2>Duplicati.GUI.TrayIcon.exe --settings-encryption-key=testtest

C:\Program Files\Duplicati 2>Crash!
Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
Unhandled exception. Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
   at Duplicati.GUI.TrayIcon.Net8.Program.Main(String[] args)

Same results when using --secret-provider=wincred://

C:\Program Files\Duplicati 2>Duplicati.GUI.TrayIcon.exe --secret-provider=wincred:// --settings-encryption-key=$duplicati-server

C:\Program Files\Duplicati 2>Server has started and is listening on port 8200

But when using testtest, “testtest” or $DuPliCaTi-SerVer as password:

C:\Program Files\Duplicati 2>Duplicati.GUI.TrayIcon.exe --secret-provider=wincred:// --settings-encryption-key=$DuPliCaTi-SerVer

C:\Program Files\Duplicati 2>Crash!
Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
Unhandled exception. Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
   at Duplicati.GUI.TrayIcon.Net8.Program.Main(String[] args)
An error occurred on server tear down: System.Threading.ThreadInterruptedException: Thread was interrupted from a waiting state.
   at System.Threading.Monitor.ObjWait(Int32 millisecondsTimeout, Object obj)
   at System.Threading.ManualResetEventSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.SpinThenBlockingWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at Duplicati.Server.Program.ShutdownModernWebserver()
   at Duplicati.Server.Program.<>c.<Main>b__60_9()
   at Duplicati.Server.Program.Main(String[] _args)

Note: I did delete the %localappdata%\Duplicati and rerun the “Duplicati.GUI.TrayIcon.exe --secret-provider=wincred:// --settings-encryption-key=$duplicati-server” command line to encrypt the database between every test I made.

Another test I made using --settings-encryption-key=testtest first to encrypt the database:

C:\Program Files\Duplicati 2>Duplicati.GUI.TrayIcon.exe --secret-provider=wincred:// --settings-encryption-key=testtest

C:\Program Files\Duplicati 2>Server has started and is listening on port 8200

Then I closed the Tray Icon, and tried with the $duplicati-server that contains the password testtest in the Credential Manager:

C:\Program Files\Duplicati 2>Duplicati.GUI.TrayIcon.exe --secret-provider=wincred:// --settings-encryption-key=$duplicati-server

C:\Program Files\Duplicati 2>Crash!
Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
Unhandled exception. Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
   at Duplicati.GUI.TrayIcon.Net8.Program.Main(String[] args)

I tested with this exact setup, and I found the problem. The secret matcher does not currently support - in the key name, so you need the key to be:

--settings-encryption-key=$duplicatiserver

This means you have to rename the key in the Windows Credential manager as well.

I will update the code to support - and _, but I am thinking of how to catch similar cases as well.

Alternative is to provide a pattern, like:

--secret-provider-pattern=$() --settings-encryption-key=$(duplicati-server)

Working like a charm when I don’t use a dash (-).

Now I did try to set “secret-provider” to “wincred://” in Settings/Default options, but when I do so, I am unable to reopen the database. Even if I add “secret-provider”, click OK then remove it and click OK, I won’t be able to reopen the database. I have to delete “%localappdata%\Duplicati” and start from the beginning.

There is no way for me to be able to start Duplicati using the default icon even if the database knows I use wincred:// and I set the environment variable SETTINGS_ENCRYPTION_KEY to “$Duplicati” (the new name I use in Credential Manager).

Even when using the full command line used to encrypt the database, it stops working as soon as I add “secret-provider” into the web interface.

My command line is:

Duplicati.GUI.TrayIcon.exe --secret-provider=wincred:// --settings-encryption-key=$Duplicati

The result is:

C:\Program Files\Duplicati 2>Crash!
Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: System.ArgumentOutOfRangeException: dueTime ('63885110400000') must be less than or equal to '4294967294'. (Parameter 'dueTime')
Actual value was 63885110400000.
   at System.ArgumentOutOfRangeException.ThrowGreater[T](T value, T other, String paramName)
   at System.Threading.Timer.Change(Int64 dueTime, Int64 period)
   at Duplicati.Server.LiveControls.Init()
   at Duplicati.Server.LiveControls..ctor(Connection connection)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Duplicati.WebserverCore.Extensions.ServiceCollectionsExtensions.<>c.<AddDuplicati>b__0_0(IServiceProvider c)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Duplicati.Library.RestAPI.FIXMEGlobal.get_WorkerThreadsManager()
   at Duplicati.Server.Database.ServerSettings.SaveSettings()
   at Duplicati.Server.Database.ServerSettings.set_ServerPortChanged(Boolean value)
   at Duplicati.Server.Program.set_ServerPortChanged(Boolean value)
   at Duplicati.Server.Program.StartWebServer(IReadOnlyDictionary`2 options, Connection connection)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> System.ArgumentOutOfRangeException: dueTime ('63885110400000') must be less than or equal to '4294967294'. (Parameter 'dueTime')
Actual value was 63885110400000.
   at System.ArgumentOutOfRangeException.ThrowGreater[T](T value, T other, String paramName)
   at System.Threading.Timer.Change(Int64 dueTime, Int64 period)
   at Duplicati.Server.LiveControls.Init()
   at Duplicati.Server.LiveControls..ctor(Connection connection)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Duplicati.WebserverCore.Extensions.ServiceCollectionsExtensions.<>c.<AddDuplicati>b__0_0(IServiceProvider c)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Duplicati.Library.RestAPI.FIXMEGlobal.get_WorkerThreadsManager()
   at Duplicati.Server.Database.ServerSettings.SaveSettings()
   at Duplicati.Server.Database.ServerSettings.set_ServerPortChanged(Boolean value)
   at Duplicati.Server.Program.set_ServerPortChanged(Boolean value)
   at Duplicati.Server.Program.StartWebServer(IReadOnlyDictionary`2 options, Connection connection)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
Unhandled exception. Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: System.ArgumentOutOfRangeException: dueTime ('63885110400000') must be less than or equal to '4294967294'. (Parameter 'dueTime')
Actual value was 63885110400000.
   at System.ArgumentOutOfRangeException.ThrowGreater[T](T value, T other, String paramName)
   at System.Threading.Timer.Change(Int64 dueTime, Int64 period)
   at Duplicati.Server.LiveControls.Init()
   at Duplicati.Server.LiveControls..ctor(Connection connection)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Duplicati.WebserverCore.Extensions.ServiceCollectionsExtensions.<>c.<AddDuplicati>b__0_0(IServiceProvider c)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Duplicati.Library.RestAPI.FIXMEGlobal.get_WorkerThreadsManager()
   at Duplicati.Server.Database.ServerSettings.SaveSettings()
   at Duplicati.Server.Database.ServerSettings.set_ServerPortChanged(Boolean value)
   at Duplicati.Server.Program.set_ServerPortChanged(Boolean value)
   at Duplicati.Server.Program.StartWebServer(IReadOnlyDictionary`2 options, Connection connection)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> System.ArgumentOutOfRangeException: dueTime ('63885110400000') must be less than or equal to '4294967294'. (Parameter 'dueTime')
Actual value was 63885110400000.
   at System.ArgumentOutOfRangeException.ThrowGreater[T](T value, T other, String paramName)
   at System.Threading.Timer.Change(Int64 dueTime, Int64 period)
   at Duplicati.Server.LiveControls.Init()
   at Duplicati.Server.LiveControls..ctor(Connection connection)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Duplicati.WebserverCore.Extensions.ServiceCollectionsExtensions.<>c.<AddDuplicati>b__0_0(IServiceProvider c)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Duplicati.Library.RestAPI.FIXMEGlobal.get_WorkerThreadsManager()
   at Duplicati.Server.Database.ServerSettings.SaveSettings()
   at Duplicati.Server.Database.ServerSettings.set_ServerPortChanged(Boolean value)
   at Duplicati.Server.Program.set_ServerPortChanged(Boolean value)
   at Duplicati.Server.Program.StartWebServer(IReadOnlyDictionary`2 options, Connection connection)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
   at Duplicati.GUI.TrayIcon.Net8.Program.Main(String[] args)

Arh, that one! I spent a lot of time figuring this out, but it is caused by (at least) fr-CA locale treating a value such as 0s to be a valid date. It has been fixed in canary builds.

You have 3 options:

  1. Don’t use fr-CA locale for date/time
  2. Manually edit the database
  3. Use a canary build

You can see the full discussion.

For step 2, you need a tool such as SQLiteBrowser, edit the file Duplicati-server.sqlite edit the table Option and change the value for startup-delay from the current 0s to a blank. Then save, and it works again.

I’m using the fr-CA locale, and replacing 0s with a blank value resolved the issue.

However, I’m still facing a problem. My objective is to launch Duplicati’s GUI executable without any command-line arguments.

When I configure secret-provider to wincred:// as a default option in the web interface, it’s added to the database as --secret-provider. Additionally, my environment variable SETTINGS_ENCRYPTION_KEY is set to $Duplicati. Given that both the secret provider and my encryption key are known, I believe I should be able to start Duplicati without any parameters using the following command line:

C:\Program Files\Duplicati 2\Duplicati.GUI.TrayIcon.exe

Unfortunately, I’m still encountering a message indicating that my encryption key is not valid.

C:\Program Files\Duplicati 2>Crash!
Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
Unhandled exception. Duplicati.Library.Interface.UserInformationException: Server crashed on startup
 ---> System.Exception: Une erreur critique s'est produite dans Duplicati: Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
 ---> Duplicati.Library.Interface.SettingsEncryptionKeyMismatchException: Encryption key used to encrypt target settings does not match current key.
   at Duplicati.Library.Encryption.EncryptedFieldHelper.Decrypt(String value, KeyInstance key)
   at Duplicati.Server.Database.Connection.DecryptSensitiveFields(String fieldValue, KeyInstance key)
   at Duplicati.Server.Database.Connection.<GetSettings>b__27_0(IDataReader rd)
   at Duplicati.Server.Database.Connection.Read[T](IDbCommand cmd, Func`2 f)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Duplicati.Server.Database.Connection.ReadFromDb[T](Func`2 f, String sql, Object[] args)
   at Duplicati.Server.Database.Connection.GetSettings(Int64 id)
   at Duplicati.Server.Database.ServerSettings.ReloadSettings()
   at Duplicati.Server.Database.ServerSettings..ctor(Connection con)
   at Duplicati.Server.Database.Connection..ctor(IDbConnection connection, Boolean disableFieldEncryption, KeyInstance key)
   at Duplicati.Server.Program.GetDatabaseConnection(Dictionary`2 commandlineOptions, Boolean silentConsole)
   at Duplicati.Server.Program.Main(String[] _args)
   --- End of inner exception stack trace ---
   at Duplicati.Server.Program.Main(String[] _args)
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper.<>c__DisplayClass5_0.<.ctor>b__0(Object dummy_arg)
   --- End of inner exception stack trace ---
   at Duplicati.GUI.TrayIcon.HostedInstanceKeeper..ctor(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, String logdir, String applicationName)
   at Duplicati.GUI.TrayIcon.Net8.Program.Main(String[] args)

The following command lines produce the same result:

Duplicati.GUI.TrayIcon.exe --secret-provider=wincred://
Duplicati.GUI.TrayIcon.exe --settings-encryption-key=$Duplicati

However, if I use both arguments, it works:

Duplicati.GUI.TrayIcon.exe --secret-provider=wincred:// --settings-encryption-key=$Duplicati

I thought default options and environment variables were always used when set.

It would also be beneficial to add --settings-encryption-key as an advanced option when it’s configured to use a credential manager. In such cases, it should only accept a name, not a literal password. Perhaps a new argument could be introduced specifically for when a name is being used. This would prevent the database from being encrypted with the literal name as the key, which happened to me.

Thank you for your time.

Yes. The issue here is that the database is encrypted, so Duplicati cannot read anything from the database during startup. For that reason, you cannot use the settings that you set in the Duplicati UI to decrypt the database.

(The reason you can set it in the settings in Duplicati is if you want another secret provider for the backup jobs).

That will not work, because that environment variable is read directly.

What you can do instead is set the environment variables like this:

> SET DUPLICATI__SECRET_PROVIDER=wincred://
> SET DUPLICATI__SETTINGS_ENCRYPTION_KEY=$Duplicati
> Duplicati.GUI.TrayIcon.exe

The DUPLICATI__* environment variables map to commandline arguments, so they are translated by the secret provider.

I’ve noticed that the --secret-provider field is unencrypted in my current test setup. Is this the expected behavior, or should it be encrypted for security reasons?

Additionally, could you explain why encrypted fields appear to be re-encrypted (perhaps with a new salt) after each application launch?

Thank you.

It should be encrypted, I have a fix for that.

The database settings are all saved when anything changes. So even if we just update the port or “last updated”, the code will rewrite all settings in the database.

The encryption used is AESCrypt (same as for file encryption). This method is slightly heavy for this use, but it includes a HMAC and a few other features. Each encryption will generate a random bulk key. The bulk key is encrypted with the real passphrase, and the contents are encrypted with the the bulk key. This setup means that any update will fully rewrite the encrypted values.

This should be fixed by having some kind of ORM layer that tracks what values to write, so only updated values are written to the database, and hence no re-encryption is done.