dotnet/orleans · error · ArgumentException

DynamoDBStorage client is not initialized

Error message

DynamoDBStorage client is not initialized

What it means

Thrown by DynamoDBTransactionalStateStorageFactory.Create<TState> when this.storage is still null. storage is assigned inside the lifecycle Init handler (Initialize), so a null storage means the silo lifecycle never reached the configured InitStage for this provider, or that Init threw and the factory is still being asked to create storage instances. It is an ordering/initialization-failure guard.

Source

Thrown at src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/DynamoDBTransactionalStateStorageFactory.cs:80

    /// <summary>
    /// Creates a transactional state storage factory.
    /// </summary>
    /// <param name="services">The service provider.</param>
    /// <param name="name">The provider name.</param>
    /// <returns>The transactional state storage factory.</returns>
    public static ITransactionalStateStorageFactory Create(IServiceProvider services, string name)
    {
        var optionsMonitor = services.GetRequiredService<IOptionsMonitor<DynamoDBTransactionalStorageOptions>>();
        return ActivatorUtilities.CreateInstance<DynamoDBTransactionalStateStorageFactory>(services, name, optionsMonitor.Get(name));
    }

    /// <inheritdoc />
    public ITransactionalStateStorage<TState> Create<TState>(string stateName, IGrainContext context) where TState : class, new()
    {
        if (this.storage is null)
        {
            throw new ArgumentException("DynamoDBStorage client is not initialized");
        }

        var partitionKey = this.MakePartitionKey(context, stateName);
        var logger = this.loggerFactory.CreateLogger<DynamoDBTransactionalStateStorage<TState>>();
        return ActivatorUtilities.CreateInstance<DynamoDBTransactionalStateStorage<TState>>(context.ActivationServices, this.storage, this.options, partitionKey, logger);
    }

    /// <inheritdoc />
    public void Participate(ISiloLifecycle lifecycle)
    {
        lifecycle.Subscribe(OptionFormattingUtilities.Name<DynamoDBTransactionalStateStorageFactory>(this.name), this.options.InitStage, Init);
    }

    private async Task Initialize(CancellationToken cancellationToken)
    {
        var stopWatch = Stopwatch.StartNew();
        var logger = this.loggerFactory.CreateLogger<DynamoDBStorage>();

View on GitHub (pinned to fca799fa70)

Solutions

  1. Check the silo startup logs for an earlier 'Initialization failed for provider ...' (LogErrorProviderInitFailed) message — the real cause is upstream in Init.
  2. Verify DynamoDBTransactionalStorageOptions (Service/region, credentials, TableName) are correct and that the table can be created/reached.
  3. Ensure InitStage is early enough that the provider is initialized before grains that use it activate.
  4. Confirm the provider is registered via AddDynamoDBTransactionalGrainStorageAsDefault / the named variant in the silo builder.

Example fix

// before: provider never initialized because options were wrong or stage too late
silo.AddDynamoDBTransactionalGrainStorage("txStore", opt =>
{
    opt.Service = ""; // empty region -> default, but maybe wrong table
});

// after: supply a valid region, table, and an early init stage
silo.AddDynamoDBTransactionalGrainStorage("txStore", opt =>
{
    opt.Service = "us-west-2";
    opt.TableName = "OrleansTransactionalState";
    opt.InitStage = ServiceLifecycleStage.RuntimeInitialize; // earlier than grain activation
});
Defensive patterns

Strategy: validation

Validate before calling

// Verify the provider is registered and will init before grains activate
var monitor = services.GetRequiredService<IOptionsMonitor<DynamoDBTransactionalStorageOptions>>();
var opt = monitor.Get("txStore");
if (string.IsNullOrWhiteSpace(opt.Service))
    throw new InvalidOperationException("DynamoDB transactional storage 'Service' (region) is not set");

Type guard

static bool IsProviderInitialized(DynamoDBTransactionalStateStorageFactory f) =>
    typeof(DynamoDBTransactionalStateStorageFactory)
        .GetField("storage", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(f) is not null;

Try / catch

try { await client.GetGrain<IMyGrain>(key).DoWork(); }
catch (ArgumentException ax) when (ax.Message == "DynamoDBStorage client is not initialized")
{
    _logger.LogCritical("Transactional storage provider failed to initialize; check silo startup logs");
    throw;
}

Prevention

When it happens

Trigger: Produced when a grain requests its transactional storage before the provider's Init stage ran (InitStage misconfigured to a late stage while grains activate earlier), or after Init failed (e.g., the DynamoDBStorage constructor threw because of bad credentials/region) but grain activation continues. Also seen if the provider was not registered correctly.

Common situations: InitStage set later than the grain-collection stage; DynamoDB connectivity/credentials failing during silo startup so Initialize() threw; misregistration of the transactional storage provider; running against DynamoDB Local that is not reachable.

Related errors


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