microsoft/semantic-kernel · critical · InvalidOperationException

Please provide valid MSGraph configuration in appsettings.De

Error message

Please provide valid MSGraph configuration in appsettings.Development.json file.

What it means

BearerAuthenticationProviderWithCancellationToken reads MSGraph:ClientId and MSGraph:TenantId from IConfiguration in its constructor and throws InvalidOperationException if either is null/empty. It then builds a PublicClientApplication, so this guard prevents MSAL from being constructed with invalid authority. The message points at appsettings.Development.json specifically because the sample loads development config there.

Source

Thrown at dotnet/samples/Demos/CopilotAgentPlugins/CopilotAgentPluginsDemoSample/BearerAuthenticationProviderWithCancellationToken.cs:27

/// "bearer" authentication scheme.
/// </summary>
public class BearerAuthenticationProviderWithCancellationToken
{
    private readonly IPublicClientApplication _client;

    /// <summary>
    /// Creates an instance of the <see cref="BearerAuthenticationProviderWithCancellationToken"/> class.
    /// </summary>
    /// <param name="configuration">The configuration instance to read settings from.</param>
    public BearerAuthenticationProviderWithCancellationToken(IConfiguration configuration)
    {
        ArgumentNullException.ThrowIfNull(configuration);
        var clientId = configuration["MSGraph:ClientId"];
        var tenantId = configuration["MSGraph:TenantId"];

        if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(tenantId))
        {
            throw new InvalidOperationException("Please provide valid MSGraph configuration in appsettings.Development.json file.");
        }

        this._client = PublicClientApplicationBuilder
            .Create(clientId)
            .WithAuthority($"https://login.microsoftonline.com/{tenantId}")
            .WithDefaultRedirectUri()
            .Build();
    }

    /// <summary>
    /// Applies the token to the provided HTTP request message.
    /// </summary>
    /// <param name="request">The HTTP request message.</param>
    /// <param name="cancellationToken"></param>
    public async Task AuthenticateRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default)
    {
        var token = await this.GetAccessTokenAsync(cancellationToken).ConfigureAwait(false);
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Add an MSGraph section with ClientId and TenantId to appsettings.Development.json.
  2. Confirm ASPNETCORE_ENVIRONMENT (or equivalent) is Development so the file is loaded.
  3. Verify the JSON key names exactly match MSGraph:ClientId / MSGraph:TenantId (case-sensitive path).
  4. As a fallback set the same keys via environment variables (MSGraph__ClientId, MSGraph__TenantId).

Example fix

// before
if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(tenantId))
    throw new InvalidOperationException("Please provide valid MSGraph configuration...");

// after (appsettings.Development.json)
{
  "MSGraph": { "ClientId": "<app-id>", "TenantId": "<tenant-id>" }
}
Defensive patterns

Strategy: validation

Validate before calling

var clientId = configuration["MSGraph:ClientId"];
var tenantId = configuration["MSGraph:TenantId"];
if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(tenantId))
    throw new InvalidOperationException(
        "Missing MSGraph:ClientId/TenantId. Add them to appsettings.Development.json or env vars MSGraph__ClientId/MSGraph__TenantId.");

Type guard

static bool HasMsGraphConfig(IConfiguration c) =>
    !string.IsNullOrEmpty(c["MSGraph:ClientId"]) && !string.IsNullOrEmpty(c["MSGraph:TenantId"]);

Prevention

When it happens

Trigger: Constructor invoked with an IConfiguration where configuration["MSGraph:ClientId"] or ["MSGraph:TenantId"] is null or empty string.

Common situations: appsettings.Development.json missing or lacking the MSGraph section, the section present but under a different key (e.g. AzureAd:ClientId), or the Development environment not active so the file isn't loaded.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/596b51af73e879d1. Report an issue: GitHub.