dotnet/orleans · critical · OrleansConfigurationException

No credentials specified. Use the…

Error message

No credentials specified. Use the AzureBlobStorageOptions.ConfigureBlobServiceClient method to configure the Azure Blob Service client.

What it means

Thrown by AzureBlobStorageOptionsValidator.ValidateConfiguration() when AzureBlobStorageOptions.CreateClient is null. This is the same credential check as the Init() path (error 240) but fires earlier — during Orleans IConfigurationValidator validation, before the provider's Init method runs. It is a fail-fast guard that surfaces missing credentials during configuration validation rather than at lifecycle initialization.

Solutions

  1. Set BlobServiceClient or call ConfigureBlobServiceClient inside the AddAzureBlobGrainStorage options delegate.
  2. Ensure any conditional configuration logic (e.g., if/else by environment) always sets credentials in all branches.
  3. Register an IValidateOptions<AzureBlobStorageOptions> or rely on the built-in validator to fail early in CI.
  4. Move the connection string into IConfiguration and read it in the configure callback so a missing value is caught immediately.

Example fix

// before
siloBuilder.AddAzureBlobGrainStorage("grainStore" /* no options delegate */);

// after
siloBuilder.AddAzureBlobGrainStorage("grainStore", o =>
{
    o.BlobServiceClient = new BlobServiceClient(configuration.GetConnectionString("AzureStorage"));
});
Defensive patterns

Strategy: validation

Validate before calling

// Register a custom IValidateOptions to catch this at configuration time
public class ValidateAzureBlobOptions : IValidateOptions<AzureBlobStorageOptions>
{
    public ValidateOptionsResult Validate(string name, AzureBlobStorageOptions options)
    {
        if (options.CreateClient is null && options.BlobServiceClient is null)
            return ValidateOptionsResult.Fail("No BlobServiceClient configured for AzureBlobStorageOptions.");
        return ValidateOptionsResult.Success;
    }
}

Try / catch

try { await host.StartAsync(ct); }
catch (OrleansConfigurationException ex) when (ex.Message.Contains("No credentials specified"))
{
    logger.LogCritical("Azure Blob Storage credentials missing — check configuration.");
    throw;
}

Prevention

When it happens

Trigger: Fires when the Orleans hosting infrastructure invokes ValidateConfiguration() on the AzureBlobStorageOptionsValidator, typically during silo build/start. Occurs when CreateClient is null because no ConfigureBlobServiceClient overload or BlobServiceClient property assignment was made.

Common situations: Same root cause as 240 — missing credentials — but caught at validation time. Common when a developer wires up the storage provider but the configuration callback that sets credentials is conditional or skipped (e.g., environment-specific config not loaded in a test environment).

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/da5e857cdca99807. Report an issue: GitHub.

Appendix: source

Thrown at src/Azure/Orleans.Persistence.AzureStorage/Providers/Storage/AzureBlobStorageOptions.cs:148

        private readonly AzureBlobStorageOptions options;
        private readonly string name;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="options">The option to be validated.</param>
        /// <param name="name">The option name to be validated.</param>
        public AzureBlobStorageOptionsValidator(AzureBlobStorageOptions options, string name)
        {
            this.options = options;
            this.name = name;
        }

        public void ValidateConfiguration()
        {
            if (this.options.CreateClient is null)
            {
                throw new OrleansConfigurationException($"No credentials specified. Use the {options.GetType().Name}.{nameof(AzureBlobStorageOptions.ConfigureBlobServiceClient)} method to configure the Azure Blob Service client.");
            }

            try
            {
                AzureBlobUtils.ValidateContainerName(options.ContainerName);
                AzureBlobUtils.ValidateBlobName(this.name);
            }
            catch (ArgumentException e)
            {
                throw new OrleansConfigurationException(
                    $"Configuration for AzureBlobStorageOptions {name} is invalid. {nameof(this.options.ContainerName)} is not valid", e);
            }
        }
    }
}

View on GitHub (pinned to fca799fa70)