dotnet/orleans · error · InvalidOperationException

AzureTableJournalStorageProvider has not been initialized. E

Error message

AzureTableJournalStorageProvider has not been initialized. Ensure the silo lifecycle has started before using journal storage.

What it means

The default InitializedTableClientProvider.GetTableClient (AzureTableJournalStorage.cs:1318) was called before SetTableClient had supplied a TableClient. The TableClient is assigned during silo lifecycle initialization; using journal storage before that phase completes throws this InvalidOperationException. It signals a lifecycle ordering bug, not a data problem.

Source

Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs:1319

        public string? JournalFormatKey { get; }

        public TableClientProvider TableClientProvider { get; }

        public AzureTableJournalStorageInstruments Instruments { get; }
    }

    internal abstract class TableClientProvider
    {
        public abstract TableClient GetTableClient();
    }

    internal sealed class InitializedTableClientProvider : TableClientProvider
    {
        private TableClient? _tableClient;

        public override TableClient GetTableClient()
            => _tableClient ?? throw new InvalidOperationException(
                $"{nameof(AzureTableJournalStorageProvider)} has not been initialized. Ensure the silo lifecycle has started before using journal storage.");

        public void SetTableClient(TableClient tableClient)
        {
            ArgumentNullException.ThrowIfNull(tableClient);
            _tableClient = tableClient;
        }
    }
}

View on GitHub (pinned to fca799fa70)

Solutions

  1. Defer journal access until after the silo/client has fully started (the storage's lifecycle OnActive has completed).
  2. In tests, call SetTableClient with a real or mock TableClient before exercising the storage.
  3. Ensure the consuming component participates in a lifecycle stage later than the storage provider.

Example fix

// before — journal used during early startup
public MyStartupService(JournalStorage s) { s.Read(...); }

// after — wait until lifecycle active
public Task OnActive(CancellationToken ct) { /* journal safe here */ }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the provider is initialized before first use
try { _ = storageShared.TableClientProvider.GetTableClient(); }
catch (InvalidOperationException) { /* not yet initialized — defer use */ }

Prevention

When it happens

Trigger: Any journal read/write issued before the AzureTableJournalStorageProvider's lifecycle OnActive has run and called SetTableClient; e.g., a grain or startup service that touches a journal during an earlier lifecycle stage.

Common situations: A hosted service or grain attempts journal access during Configure or earlier lifecycle phases; a test instantiates the storage and calls methods without driving the lifecycle; misordered DI such that a consumer resolves and uses the storage before the provider is initialized.

Related errors


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