{"record":{"id":"7fa21d5f15ed8050","repo":"duplicati/duplicati","slug":"ssh-pubkey","errorCode":null,"errorMessage":"ssh-pubkey","messagePattern":"ssh-pubkey","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Duplicati/Library/Backend/SSHv2/KeyUploader.cs","lineNumber":52,"sourceCode":"        private const string AUTHORIZED_KEYS_PATH = SSH_FOLDER + \"/\" + AUTHORIZED_KEYS_FILE;\r\n\r\n        private const short SSH_FOLDER_PERMISSIONS = 755;// 0x1ED /*755*/;\r\n        private const short AUTHORIZED_KEYS_PERMISSIONS = 644; //0x1A4 /*644*/;\r\n        private const short AUTHORIZED_KEYS_BACKUP_PERMISSIONS = 600; //0x180 /*600*/;\r\n\r\n        #region IWebModule implementation\r\n\r\n        public async Task<IDictionary<string, string>> Execute(IDictionary<string, string> options, CancellationToken cancellationToken)\r\n        {\r\n            var res = new Dictionary<string, string>();\r\n\r\n            options.TryGetValue(OPTION_URL, out var url);\r\n            options.TryGetValue(OPTION_KEY, out var pubkey_s);\r\n\r\n            if (string.IsNullOrWhiteSpace(url))\r\n                throw new ArgumentException(OPTION_URL);\r\n            if (string.IsNullOrWhiteSpace(pubkey_s))\r\n                throw new ArgumentException(OPTION_KEY);\r\n\r\n            var uri = new Utility.RelaxedUri(url);\r\n            foreach (var key in uri.QueryParameters.AllKeys)\r\n                if (!string.IsNullOrWhiteSpace(key))\r\n                    options[key] = uri.QueryParameters[key] ?? \"\";\r\n\r\n\r\n            pubkey_s = pubkey_s.Trim();\r\n            var pubkey = pubkey_s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x.Length > 0).ToArray();\r\n\r\n            if (pubkey.Length != 3)\r\n                throw new ArgumentException(OPTION_KEY);\r\n\r\n            using (var connection = new SSHv2(url, (Dictionary<string, string?>)options))\r\n            {\r\n                var client = await connection.CreateConnection(cancellationToken).ConfigureAwait(false);\r\n                try\r\n                {\r","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/duplicati/duplicati/blob/3f348be3e33f5d72d414e3ad55839c2ba34dda67/Duplicati/Library/Backend/SSHv2/KeyUploader.cs#L34-L70","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide the 'ssh-pubkey' option with the full public key string.","Generate a key first using the ssh-keygen module, then copy the public key output into ssh-pubkey.","Ensure the option name is exactly 'ssh-pubkey'."],"exampleFix":"// before\noptions[\"ssh-pubkey\"] = \"\"; // missing pubkey\n\n// after\noptions[\"ssh-pubkey\"] = \"ssh-rsa AAAAB3...== user@host\";","handlingStrategy":"validation","validationCode":"// Validate the ssh-pubkey option before calling Execute\nif (!options.TryGetValue(\"ssh-pubkey\", out var pubkey) || string.IsNullOrWhiteSpace(pubkey))\n    throw new InvalidOperationException(\"The 'ssh-pubkey' option is required.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var result = await keyUploader.Execute(options, cancellationToken);\n}\ncatch (ArgumentException ex) when (ex.ParamName == \"ssh-pubkey\" && !options.ContainsKey(\"ssh-pubkey\"))\n{\n    Console.Error.WriteLine(\"Missing 'ssh-pubkey'. Generate or paste the public key.\");\n    throw;\n}","preventionTips":["Generate a key pair first using the ssh-keygen module.","Copy the .pub file content into the ssh-pubkey option.","Validate required options before module execution."],"tags":["ssh","configuration","validation","key-upload"],"backgroundTag":null,"analyzedSha":"3f348be3e33f5d72d414e3ad55839c2ba34dda67","analyzedAt":"2026-08-13T16:48:27.008Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}