dotnet/orleans · error · InvalidOperationException
AzureBlobJournalStorageProvider has not been initialized. En
Error message
AzureBlobJournalStorageProvider has not been initialized. Ensure the silo lifecycle has started before using journal storage.
What it means
Thrown by AzureBlobJournalStorageProvider.GetDefaultContainerClient when the default container client is null, meaning the provider has not run its lifecycle initialization. The provider subscribes to the silo lifecycle at RuntimeInitialize stage and creates the container there; calling ListAsync or other methods before that stage completes yields this error.
Source
Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureBlobJournalStorageProvider.cs:104
}
foreach (var journalId in journalIds.OrderBy(static journalId => journalId.Value, StringComparer.Ordinal))
{
cancellationToken.ThrowIfCancellationRequested();
yield return journalId;
}
}
public void Participate(ISiloLifecycle observer)
{
observer.Subscribe(
nameof(AzureBlobJournalStorageProvider),
ServiceLifecycleStage.RuntimeInitialize,
onStart: Initialize);
}
private BlobContainerClient GetDefaultContainerClient()
=> _defaultContainer ?? throw new InvalidOperationException(
$"{nameof(AzureBlobJournalStorageProvider)} has not been initialized. Ensure the silo lifecycle has started before using journal storage.");
private static bool TryParseJournalId(string value, out JournalId journalId)
{
try
{
journalId = new JournalId(value);
return true;
}
catch (ArgumentException)
{
journalId = default;
return false;
}
}
private static IJournalFormat GetJournalFormat(IServiceProvider serviceProvider, string journalFormatKey)
{View on GitHub (pinned to fca799fa70)
Solutions
- Ensure the silo is fully started before calling ListAsync; in tests, use a test hosting harness that drives the lifecycle.
- Delay listing journals until after the RuntimeInitialize lifecycle stage.
- If you need listing outside the silo, construct a standalone BlobContainerClient and query the container directly.
Example fix
// before (in a test)
var provider = new AzureBlobJournalStorageProvider(...);
await foreach (var id in provider.ListAsync()) { ... } // throws: not initialized
// after
await provider.Participate(...); // or use a TestHost that runs lifecycle stages
await foreach (var id in provider.ListAsync()) { ... } Defensive patterns
Strategy: validation
Validate before calling
// In a test harness, drive the lifecycle before calling ListAsync:
var lifecycle = new TestSiloLifecycle();
provider.Participate(lifecycle);
await lifecycle.OnStart(RuntimeInitializeStage);
await foreach (var id in provider.ListAsync()) { ... } Try / catch
try { await foreach (var id in provider.ListAsync(ct)) { ... } }
catch (InvalidOperationException ex) when (ex.Message.Contains("has not been initialized"))
{
logger.LogWarning("Journal storage queried before silo RuntimeInitialize; deferring.");
} Prevention
- Use a test host that drives the silo lifecycle in unit/integration tests.
- Delay journal enumeration until after the hosting stage completes.
- Guard entry points that call GetDefaultContainerClient with a lifecycle-started flag.
When it happens
Trigger: Invoking provider.ListAsync(...) (or any path through GetDefaultContainerClient) before the silo lifecycle has reached RuntimeInitialize and run the Initialize callback. Commonly happens in tests, startup hooks, or grain constructors that run before the silo is fully started.
Common situations: Unit/integration tests that construct the provider directly without driving the lifecycle; calling ListAsync from a grain's OnActivateAsync before the hosting stage completes; ordering misconfiguration where journal storage is used before RuntimeInitialize.
Related errors
- DynamoDBStorage client is not initialized
- Journal format key '{journalFormatKey}' requires keyed servi
- Journal format key '{journalFormatKey}' resolved format '{jo
- The configured journal format key must be non-empty.
- Azure Blob journal WAL ended before the checkpoint offset wa
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/b81c4559fc93b3a9.
Report an issue: GitHub.