dotnet/AspNetCore.Docs · critical · Exception

Null EmailAuthKey

Error message

Null EmailAuthKey

What it means

Exception("Null EmailAuthKey") thrown by the sample EmailSender before calling the Mandrill API. The IOptions<AuthMessageSenderOptions>.EmailAuthKey is read in SendEmailAsync; if it is null or empty the sample refuses to send because the API key is required to authenticate with Mandrill. Guards against sending with no credentials.

Source

Thrown at aspnetcore/blazor/security/account-confirmation-and-password-recovery.md:208

        string confirmationLink) => SendEmailAsync(email, "Confirm your email",
        "<html lang=\"en\"><head></head><body>Please confirm your account by " +
        $"<a href='{confirmationLink}'>clicking here</a>.</body></html>");

    public Task SendPasswordResetLinkAsync(ApplicationUser user, string email,
        string resetLink) => SendEmailAsync(email, "Reset your password",
        "<html lang=\"en\"><head></head><body>Please reset your password by " +
        $"<a href='{resetLink}'>clicking here</a>.</body></html>");

    public Task SendPasswordResetCodeAsync(ApplicationUser user, string email,
        string resetCode) => SendEmailAsync(email, "Reset your password",
        "<html lang=\"en\"><head></head><body>Please reset your password " +
        $"using the following code:<br>{resetCode}</body></html>");

    public async Task SendEmailAsync(string toEmail, string subject, string message)
    {
        if (string.IsNullOrEmpty(Options.EmailAuthKey))
        {
            throw new Exception("Null EmailAuthKey");
        }

        await Execute(Options.EmailAuthKey, subject, message, toEmail);
    }

    public async Task Execute(string apiKey, string subject, string message, 
        string toEmail)
    {
        var api = new MandrillApi(apiKey);
        var mandrillMessage = new MandrillMessage("sarah@contoso.com", toEmail, 
            subject, message);
        await api.Messages.SendAsync(mandrillMessage);

        logger.LogInformation("Email to {EmailAddress} sent!", toEmail);
    }
}
```

View on GitHub (pinned to c67a80103a)

Solutions

  1. Set the EmailAuthKey in user secrets (Development) or environment variables/secrets store (Production): dotnet user-secrets set "EmailAuthKey" "<key>".
  2. Confirm AuthMessageSenderOptions is bound via builder.Configuration.GetSection(...).Get<AuthMessageSenderOptions>() or IOptions<AuthMessageSenderOptions>.
  3. Validate options at startup (ValidateOnStart) so misconfiguration fails fast rather than at first email send.
  4. Throw a more specific ConfigurationException with the key name for clearer diagnostics.

Example fix

// before
if (string.IsNullOrEmpty(Options.EmailAuthKey))
{
    throw new Exception("Null EmailAuthKey");
}

// after — validated options + clearer exception
builder.Services.AddOptions<AuthMessageSenderOptions>()
    .Bind(builder.Configuration.GetSection("AuthMessageSender"))
    .ValidateDataAnnotations()
    .ValidateOnStart();

// in sender
if (string.IsNullOrWhiteSpace(Options.EmailAuthKey))
{
    throw new InvalidOperationException(
        "Configuration value 'AuthMessageSender:EmailAuthKey' is missing. " +
        "Set it via user-secrets (Development) or environment variable (Production).");
}
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(builder.Configuration["AuthMessageSender:EmailAuthKey"])) {
    throw new InvalidOperationException("EmailAuthKey is not configured.");
}

Try / catch

try { await emailSender.SendEmailAsync(to, subject, body); }
catch (Exception ex) when (ex.Message.Contains("EmailAuthKey"))
{
    logger.LogCritical(ex, "Email provider not configured.");
}

Prevention

When it happens

Trigger: EmailAuthKey configuration value is missing from appsettings/secrets/user-secrets, or the AuthMessageSenderOptions was never bound from configuration. Any password-reset/confirmation flow that triggers SendEmailAsync will throw.

Common situations: Forgetting to set the EmailAuthKey user secret in Development; deployment missing the environment variable/secret; configuration section name mismatch so options binding yields null; running locally without `dotnet user-secrets set`.

Related errors


AI-assisted analysis of dotnet/AspNetCore.Docs@c67a80103a (2026-08-13). Data as JSON: /api/errors/7ab944253e755887. Report an issue: GitHub.