{"record":{"id":"61b08012fc411d85","repo":"duplicati/duplicati","slug":"no-default-secret-provider-is-available-for-this-s","errorCode":null,"errorMessage":"No default secret provider is available for this system","messagePattern":"No default secret provider is available for this system","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Duplicati/Library/DynamicLoader/SecretProviderLoader.cs","lineNumber":154,"sourceCode":"        else if (config.StartsWith(\"%\") && config.EndsWith(\"%\"))\n        {\n            envName = config[1..^1];\n        }\n\n        if (envName != null)\n        {\n            var result = Environment.GetEnvironmentVariable(envName.ToUpperInvariant());\n            if (string.IsNullOrEmpty(result))\n                throw new ArgumentException($\"The environment variable {envName} was not found\");\n\n            config = result;\n        }\n\n        if (string.Equals(config, \"default://\", StringComparison.OrdinalIgnoreCase))\n        {\n            var defaultProvider = await GetDefaultSecretProviderForOperatingSystem(initialize, cancellationToken).ConfigureAwait(false);\n            if (defaultProvider == null)\n                throw new InvalidOperationException(\"No default secret provider is available for this system\");\n\n            return defaultProvider;\n        }\n\n        var uri = new Uri(config);\n        var key = uri.Scheme;\n\n        var providerType = Modules.FirstOrDefault(p => p.Key == key)\n            ?? throw new ArgumentException($\"No secret provider found for key {key}\");\n\n        if (Activator.CreateInstance(providerType.GetType()) is not ISecretProvider provider)\n            throw new InvalidOperationException($\"Failed to create an instance of {providerType}\");\n\n        if (initialize)\n            await provider.InitializeAsync(uri, cancellationToken).ConfigureAwait(false);\n\n        return provider;\n    }","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/duplicati/duplicati/blob/3f348be3e33f5d72d414e3ad55839c2ba34dda67/Duplicati/Library/DynamicLoader/SecretProviderLoader.cs#L136-L172","documentation":"Thrown by SecretProviderLoader.CreateInstanceAsync when config is 'default://' and GetDefaultSecretProviderForOperatingSystem returns null. The default provider is platform-specific: Windows uses WindowsCredentialManagerProvider, macOS uses MacOSKeyChainProvider, and Linux uses LibSecretLinuxProvider only when IsSupported returns true (i.e. a DBus secret service such as gnome-keyring or kwallet is available). On Linux without such a service, or on an unsupported OS, the method returns null.","triggerScenarios":"Using the 'default://' config on a Linux host with no running secret service daemon, or on an OS none of the platform branches match.","commonSituations":"Headless Linux servers / containers without gnome-keyring or kwallet; CI runners with no DBus secret service; minimal Alpine images lacking the libsecret native libraries.","solutions":["Install and start a secret service (gnome-keyring with ssh prompting, or kwallet) and ensure the process can talk to DBus.","Specify an explicit provider config (e.g. 'prompt://', a file-based provider) instead of relying on 'default://'.","For containers, prefer passing the secret via environment variable indirection that resolves to an explicit, always-available provider."],"exampleFix":"// before\nvar p = await SecretProviderLoader.CreateInstanceAsync(\"default://\", true, ct);\n\n// after\nvar p = await SecretProviderLoader.CreateInstanceAsync(\"default://\", true, ct);\n// catch InvalidOperationException and fall back:\n//   var p = await SecretProviderLoader.CreateInstanceAsync(\"prompt://\", true, ct);","handlingStrategy":"fallback","validationCode":"// No direct pre-check; guard via the OS support probe the provider itself exposes.\nif (OperatingSystem.IsLinux())\n{\n    var probe = new Duplicati.Library.SecretProvider.LibSecretLinuxProvider();\n    if (!await probe.IsSupported(ct).ConfigureAwait(false))\n        // do not use 'default://' here\n        config = \"prompt://\";\n}","typeGuard":"null","tryCatchPattern":"try { p = await SecretProviderLoader.CreateInstanceAsync(\"default://\", true, ct); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"No default secret provider\"))\n{\n    logger.LogWarning(\"No OS secret store; falling back to an explicit provider.\");\n    p = await SecretProviderLoader.CreateInstanceAsync(\"prompt://\", true, ct);\n}","preventionTips":["On headless Linux, install and unlock gnome-keyring or use an explicit provider.","In containers, prefer an explicit provider config over 'default://'.","Document that 'default://' requires a platform secret store to be present."],"tags":["secrets","configuration","linux","os"],"backgroundTag":null,"analyzedSha":"3f348be3e33f5d72d414e3ad55839c2ba34dda67","analyzedAt":"2026-08-13T16:48:27.008Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}