dotnet/orleans · error · OrleansConfigurationException

Invalid {nameof(AdoNetGrainStorageOptions)} values for {name

Error message

Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} "{name}". Configure exactly one of {nameof(options.ConnectionString)} or {nameof(options.DataSource)}.

What it means

Thrown by the AdoNetGrainStorageOptionsValidator when both ConnectionString and DataSource are set, or neither is. Grain storage needs exactly one connection source. The equality check `IsNullOrWhiteSpace(ConnectionString) == (DataSource is null)` is true for both unset and both-set.

Source

Thrown at src/AdoNet/Orleans.Persistence.AdoNet/Options/AdoNetGrainStorageOptions.cs:102

        /// <param name="configurationOptions">The option to be validated.</param>
        /// <param name="name">The name of the option to be validated.</param>
        public AdoNetGrainStorageOptionsValidator(AdoNetGrainStorageOptions configurationOptions, string name)
        {
            this.options = configurationOptions ?? throw new OrleansConfigurationException($"Invalid AdoNetGrainStorageOptions for AdoNetGrainStorage {name}. Options is required.");
            this.name = name;
        }

        /// <inheritdoc cref="IConfigurationValidator"/>
        public void ValidateConfiguration()
        {
            if (string.IsNullOrWhiteSpace(this.options.Invariant))
            {
                throw new OrleansConfigurationException($"Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} \"{name}\". {nameof(options.Invariant)} is required.");
            }

            if (string.IsNullOrWhiteSpace(this.options.ConnectionString) == (this.options.DataSource is null))
            {
                throw new OrleansConfigurationException($"Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} \"{name}\". Configure exactly one of {nameof(options.ConnectionString)} or {nameof(options.DataSource)}.");
            }

            if (this.options.HashPicker == null)
            {
                throw new OrleansConfigurationException($"Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} {name}. {nameof(options.HashPicker)} is required.");
            }
        }
    }

    /// <summary>
    /// Provides default configuration HashPicker for AdoNetGrainStorageOptions.
    /// </summary>
    public class DefaultAdoNetGrainStorageOptionsHashPickerConfigurator : IPostConfigureOptions<AdoNetGrainStorageOptions>
    {
        public void PostConfigure(string? name, AdoNetGrainStorageOptions options)
        {
            // preserving explicitly configured HashPicker
            if (options.HashPicker != null)

View on GitHub (pinned to fca799fa70)

Solutions

  1. Set exactly one of options.ConnectionString or options.DataSource for the named storage.
  2. Drop the duplicate if you migrated from ConnectionString to DataSource.
  3. Confirm the appsettings.json storage section contains exactly one connection field.

Example fix

// before
builder.AddAdoNetGrainStorage("profile", o =>
{
    o.Invariant = AdoNetInvariants.InvariantNameSqlServer;
    // no connection -> error
});

// after
builder.AddAdoNetGrainStorage("profile", o =>
{
    o.Invariant = AdoNetInvariants.InvariantNameSqlServer;
    o.ConnectionString = "Server=.;Database=Orleans;Trusted_Connection=True;";
});
Defensive patterns

Strategy: validation

Validate before calling

static void CheckStorageConnection(AdoNetGrainStorageOptions o)
{
    var exactlyOne = string.IsNullOrWhiteSpace(o.ConnectionString) != (o.DataSource is null);
    if (!exactlyOne)
        throw new InvalidOperationException("Set exactly one of ConnectionString or DataSource for grain storage.");
}

Prevention

When it happens

Trigger: ValidateConfiguration() runs on AdoNetGrainStorageOptions with neither connection field set, or with both a ConnectionString and a DbDataSource supplied.

Common situations: Registering storage with only an Invariant; supplying ConnectionString while also wiring a DbDataSource for connection pooling; partial migration leaving both populated.

Related errors


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