dotnet/orleans · critical · OrleansConfigurationException

No credentials specified. Use the AzureBlobStorageOptions.Co

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.

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)

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.