duplicati/duplicati · error · ArgumentException

ssh-pubkey

Error message

ssh-pubkey

What it means

Thrown in KeyUploader.Execute (an ArgumentException) when the 'ssh-pubkey' option is null, empty, or whitespace. The module needs the public key string to install it into the remote authorized_keys file. The ArgumentException param name is 'ssh-pubkey'.

Source

Thrown at Duplicati/Library/Backend/SSHv2/KeyUploader.cs:52

        private const string AUTHORIZED_KEYS_PATH = SSH_FOLDER + "/" + AUTHORIZED_KEYS_FILE;

        private const short SSH_FOLDER_PERMISSIONS = 755;// 0x1ED /*755*/;
        private const short AUTHORIZED_KEYS_PERMISSIONS = 644; //0x1A4 /*644*/;
        private const short AUTHORIZED_KEYS_BACKUP_PERMISSIONS = 600; //0x180 /*600*/;

        #region IWebModule implementation

        public async Task<IDictionary<string, string>> Execute(IDictionary<string, string> options, CancellationToken cancellationToken)
        {
            var res = new Dictionary<string, string>();

            options.TryGetValue(OPTION_URL, out var url);
            options.TryGetValue(OPTION_KEY, out var pubkey_s);

            if (string.IsNullOrWhiteSpace(url))
                throw new ArgumentException(OPTION_URL);
            if (string.IsNullOrWhiteSpace(pubkey_s))
                throw new ArgumentException(OPTION_KEY);

            var uri = new Utility.RelaxedUri(url);
            foreach (var key in uri.QueryParameters.AllKeys)
                if (!string.IsNullOrWhiteSpace(key))
                    options[key] = uri.QueryParameters[key] ?? "";


            pubkey_s = pubkey_s.Trim();
            var pubkey = pubkey_s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x.Length > 0).ToArray();

            if (pubkey.Length != 3)
                throw new ArgumentException(OPTION_KEY);

            using (var connection = new SSHv2(url, (Dictionary<string, string?>)options))
            {
                var client = await connection.CreateConnection(cancellationToken).ConfigureAwait(false);
                try
                {

View on GitHub (pinned to 3f348be3e3)

Solutions

  1. Provide the 'ssh-pubkey' option with the full public key string.
  2. Generate a key first using the ssh-keygen module, then copy the public key output into ssh-pubkey.
  3. Ensure the option name is exactly 'ssh-pubkey'.

Example fix

// before
options["ssh-pubkey"] = ""; // missing pubkey

// after
options["ssh-pubkey"] = "ssh-rsa AAAAB3...== user@host";
Defensive patterns

Strategy: validation

Validate before calling

// Validate the ssh-pubkey option before calling Execute
if (!options.TryGetValue("ssh-pubkey", out var pubkey) || string.IsNullOrWhiteSpace(pubkey))
    throw new InvalidOperationException("The 'ssh-pubkey' option is required.");

Try / catch

try
{
    var result = await keyUploader.Execute(options, cancellationToken);
}
catch (ArgumentException ex) when (ex.ParamName == "ssh-pubkey" && !options.ContainsKey("ssh-pubkey"))
{
    Console.Error.WriteLine("Missing 'ssh-pubkey'. Generate or paste the public key.");
    throw;
}

Prevention

When it happens

Trigger: KeyUploader.Execute is called with an options dictionary where the 'ssh-pubkey' key is missing or blank. This is checked immediately after the ssh-url validation, before any connection is made.

Common situations: The user forgot to paste the public key; the key was generated separately but not copied into the ssh-pubkey option; the option name was mistyped.

Related errors


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