{"record":{"id":"ddf21a78144be5bf","repo":"duplicati/duplicati","slug":"openstackmissingusername","errorCode":"OpenStackMissingUsername","errorMessage":"Missing required option: {0}","messagePattern":"Missing required option: (.+?)","errorType":"validation","errorClass":"UserInformationException","httpStatus":null,"severity":"error","filePath":"Duplicati/Library/Backend/OpenStack/OpenStackStorage.cs","lineNumber":129,"sourceCode":"\r\n        m_container = uri.Host ?? \"\";\r\n        m_prefix = Util.AppendDirSeparator(\"/\" + uri.Path, \"/\");\r\n        _timeouts = TimeoutOptionsHelper.Parse(options);\r\n\r\n        // For OpenStack we do not use a leading slash\r\n        if (m_prefix.StartsWith(\"/\", StringComparison.Ordinal))\r\n            m_prefix = m_prefix.Substring(1);\r\n\r\n        var auth = AuthOptionsHelper.Parse(options, uri.Username, uri.Password);\r\n\r\n        options.TryGetValue(DOMAINNAME_OPTION, out m_domainName);\r\n        options.TryGetValue(TENANTNAME_OPTION, out m_tenantName);\r\n        options.TryGetValue(VERSION_OPTION, out m_version);\r\n        options.TryGetValue(APIKEY_OPTION, out m_apikey);\r\n        options.TryGetValue(REGION_OPTION, out m_region);\r\n\r\n        if (!auth.HasUsername)\r\n            throw new UserInformationException(Strings.OpenStack.MissingOptionError(AuthOptionsHelper.AuthUsernameOption), \"OpenStackMissingUsername\");\r\n\r\n        m_username = auth.Username!;\r\n        m_password = auth.Password;\r\n        var authUri = options.GetValueOrDefault(AUTHURI_OPTION);\r\n        if (string.IsNullOrWhiteSpace(authUri))\r\n            throw new UserInformationException(Strings.OpenStack.MissingOptionError(AUTHURI_OPTION), \"OpenStackMissingAuthUri\");\r\n\r\n        m_authUri = authUri;\r\n        if (string.IsNullOrWhiteSpace(m_version) && m_authUri.EndsWith(\"/v3\", StringComparison.OrdinalIgnoreCase))\r\n            m_version = \"v3\";\r\n\r\n        switch (m_version)\r\n        {\r\n            case \"v3\":\r\n                if (string.IsNullOrWhiteSpace(m_password))\r\n                    throw new UserInformationException(Strings.OpenStack.MissingOptionError(AuthOptionsHelper.AuthPasswordOption), \"OpenStackMissingPassword\");\r\n                if (string.IsNullOrWhiteSpace(m_domainName))\r\n                    throw new UserInformationException(Strings.OpenStack.MissingOptionError(DOMAINNAME_OPTION), \"OpenStackMissingDomainName\");\r","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/duplicati/duplicati/blob/3f348be3e33f5d72d414e3ad55839c2ba34dda67/Duplicati/Library/Backend/OpenStack/OpenStackStorage.cs#L111-L147","documentation":"OpenStackStorage constructor throws UserInformationException('OpenStackMissingUsername') when AuthOptionsHelper.Parse(options, uri.Username, uri.Password) yields an auth object with !HasUsername. The username normally comes from the connection URI; its absence means the credentials were not supplied.","triggerScenarios":"Constructor at line 128-129: auth.HasUsername is false because uri.Username is empty and no equivalent option populates it.","commonSituations":"Backend URL written without the 'username@' segment; credentials moved into options but the OpenStack helper only reads username from the URI; secret/credential migration that dropped the username.","solutions":["Put the username in the backend URL: openstack://username@auth-endpoint/...","Confirm the URI parsing path the backend uses (AuthOptionsHelper reads username from the URI authority).","Re-create the backend via the GUI which splits username/host correctly."],"exampleFix":"// before\nopenstack://auth.example.com/v3/container\n\n// after\nopenstack://myuser@auth.example.com/v3/container","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(uri.Username))\n    throw new InvalidOperationException(\"OpenStack backend requires a username in the connection URI.\");","typeGuard":null,"tryCatchPattern":"try { storage = new OpenStackStorage(url, opts); }\ncatch (UserInformationException ex) when (ex.HelpID == \"OpenStackMissingUsername\")\n{ ReportConfigError(ex.Message); throw; }","preventionTips":["Always include the username@ segment in the OpenStack URI.","Validate credentials before persisting the backend."],"tags":["configuration","openstack","validation","backend","duplicati"],"backgroundTag":null,"analyzedSha":"3f348be3e33f5d72d414e3ad55839c2ba34dda67","analyzedAt":"2026-08-13T16:48:27.008Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}