OrchardCMS/OrchardCore · error · InvalidEmailProviderException

' ' is an invalid Email provider name.

Error message

'${name}' is an invalid Email provider name.

What it means

DefaultEmailProviderResolver resolves an IEmailProvider by configured provider name. If the requested name exists in EmailProviderOptions.Providers the configured type is instantiated; otherwise it throws InvalidEmailProviderException with the offending name. This message surfaces when code requests an email provider name that is not configured/registered.

Solutions

  1. Verify EmailProviderOptions.Providers actually contains the requested key (check Email admin settings or options setup)
  2. Fix the persisted/default EmailSettings to reference an existing provider name
  3. Register the provider type in EmailProviderOptions before resolving it
  4. Guard the caller: validate the name against the resolver's configured names before calling GetAsync

Example fix

// before
var provider = await _emailProviderResolver.GetAsync("sendgrid"); // not configured
// after
var options = _optionsMonitor.CurrentValue;
if (options.Providers.ContainsKey("sendgrid"))
{
    provider = await _emailProviderResolver.GetAsync("sendgrid");
}
Defensive patterns

Strategy: validation

Validate before calling

var options = _optionsMonitor.CurrentValue;
if (!options.Providers.ContainsKey(providerName))
    throw new InvalidOperationException($"Email provider '{providerName}' is not configured");

Type guard

bool IsConfiguredProvider(string name, IOptionsMonitor<EmailProviderOptions> o) => o.CurrentValue.Providers.ContainsKey(name);

Try / catch

try { provider = await resolver.GetAsync(name); } catch (InvalidEmailProviderException ex) { _logger.LogError(ex, "Unknown email provider {Name}", name); provider = await resolver.GetAsync(EmailConstants.DefaultProvider); }

Prevention

When it happens

Trigger: Calling IEmailProviderResolver.GetAsync(name) (or resolving the default provider path) with a name that has no matching key in EmailProviderOptions.Providers — e.g. settings stored a provider name from a different module configuration or before a rename.

Common situations: Renaming a provider (e.g. smtp) while persisted EmailSettings still reference the old name; multi-tenant setups where one tenant has the provider configured and another does not; typos in the provider name passed to GetAsync.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/b3744843d11e1374. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Email.Core/Services/DefaultEmailProviderResolver.cs:39

    public ValueTask<IEmailProvider> GetAsync(string name = null)
    {
        var emailOptions = _emailOptions.CurrentValue;
        var providerOptions = _providerOptions.CurrentValue;

        if (string.IsNullOrEmpty(name))
        {
            name = emailOptions.DefaultProviderName;
        }

        if (!string.IsNullOrEmpty(name))
        {
            if (providerOptions.Providers.TryGetValue(name, out var providerType))
            {
                return ValueTask.FromResult(_serviceProvider.CreateInstance<IEmailProvider>(providerType.Type));
            }

            throw new InvalidEmailProviderException(name);
        }

        return ValueTask.FromResult<IEmailProvider>(null);
    }
}

View on GitHub (pinned to 4306c0717f)