dotnet/orleans · critical · InvalidOperationException
No Azure Table service client was configured. Set TableServi
Error message
No Azure Table service client was configured. Set TableServiceClient or call ConfigureTableServiceClient.
What it means
Thrown during AzureTableJournalStorageProvider.Initialize when AzureTableJournalStorageOptions.CreateClient is null, meaning no TableServiceClient was provided. The provider cannot connect to Azure Tables without a client, so it aborts silo initialization rather than failing on the first storage call.
Source
Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorageProvider.cs:39
IServiceProvider serviceProvider,
ILogger<AzureTableJournalStorage> logger,
AzureTableJournalStorageInstruments? instruments = null)
{
_options = options.Value;
var journalFormatKey = ValidateJournalFormatKey(managerOptions.Value.JournalFormatKey);
ValidateJournalFormat(serviceProvider, journalFormatKey);
_shared = new AzureTableJournalStorage.AzureTableJournalStorageShared(
logger,
options,
_tableClientProvider,
instruments ?? AzureTableJournalStorageInstruments.CreateForDirectConstruction(),
journalFormatKey);
}
private async Task Initialize(CancellationToken cancellationToken)
{
var createClient = _options.CreateClient
?? throw new InvalidOperationException(
$"No Azure Table service client was configured. Set {nameof(AzureTableJournalStorageOptions.TableServiceClient)} " +
$"or call {nameof(AzureTableJournalStorageOptions.ConfigureTableServiceClient)}.");
var client = await createClient(cancellationToken).ConfigureAwait(false)
?? throw new InvalidOperationException("The configured Azure Table service client factory returned null.");
var table = client.GetTableClient(_options.TableName);
await table.CreateIfNotExistsAsync(cancellationToken).ConfigureAwait(false);
_tableClientProvider.SetTableClient(table);
}
public IJournalStorage CreateStorage(JournalId journalId)
{
if (journalId.IsDefault)
{
throw new ArgumentException("The journal id must not be the default value.", nameof(journalId));
}
return new AzureTableJournalStorage(_shared, journalId);
}View on GitHub (pinned to fca799fa70)
Solutions
- Call one of options.ConfigureTableServiceClient(connectionString | Uri | Uri+credential) before startup.
- Set options.TableServiceClient directly with a prebuilt TableServiceClient.
- Verify your AddAzureTableJournaling configuration lambda actually invokes a ConfigureTableServiceClient overload.
Example fix
// before
builder.AddAzureTableJournaling(opts => { opts.TableName = "journal"; });
// after
builder.AddAzureTableJournaling(opts =>
{
opts.TableName = "journal";
opts.ConfigureTableServiceClient(builder.Configuration.GetConnectionString("AzureStorage"));
}); Defensive patterns
Strategy: validation
Validate before calling
if (options.CreateClient is null && options.TableServiceClient is null)
throw new InvalidOperationException("Configure a TableServiceClient before startup."); Type guard
static bool IsTableClientConfigured(AzureTableJournalStorageOptions o) => o.TableServiceClient is not null || o.CreateClient is not null;
Prevention
- Always call ConfigureTableServiceClient inside your AddAzureTableJournaling lambda.
- Add a startup health check that the options have a client configured.
- Bind connection strings from a verified configuration source.
When it happens
Trigger: The options were registered (e.g. via AddAzureTableJournaling) but neither TableServiceClient was set nor any ConfigureTableServiceClient overload was called, then the silo lifecycle triggers Initialize.
Common situations: Forgetting to call ConfigureTableServiceClient in Program.cs; relying on a config section that did not bind credentials; misordering of configuration such that the client setup callback never ran.
Related errors
- The configured Azure Table service client factory returned n
- Journal format key '{journalFormatKey}' requires keyed servi
- Journal format key '{journalFormatKey}' resolved format '{jo
- The configured journal format key must be non-empty.
- Value cannot be null.
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/07f72143343deab6.
Report an issue: GitHub.