dotnet/orleans · error · OrleansConfigurationException
Invalid {nameof(AdoNetGrainStorageOptions)} values for {name
Error message
Invalid {nameof(AdoNetGrainStorageOptions)} values for {nameof(AdoNetGrainStorage)} "{name}". {nameof(options.Invariant)} is required. What it means
Thrown by the AdoNetGrainStorageOptionsValidator when Invariant is null or whitespace. AdoNetGrainStorageOptions.Invariant defaults to SQL Server, so this only fires if the default was explicitly cleared to empty or the options object was constructed/serialized without populating Invariant.
Source
Thrown at src/AdoNet/Orleans.Persistence.AdoNet/Options/AdoNetGrainStorageOptions.cs:97
private readonly string name;
/// <summary>
/// Constructor
/// </summary>
/// <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>View on GitHub (pinned to fca799fa70)
Solutions
- Remove any empty "Invariant" override in configuration so the SQL Server default applies.
- Set options.Invariant = AdoNetInvariants.InvariantNameSqlServer (or PostgreSql/MySql as needed) explicitly.
- Bind options with a binder that preserves defaults rather than overwriting with null.
Example fix
// before // appsettings.json: "Invariant": "" (wipes default) // after // appsettings.json: omit Invariant, or: "Invariant": "System.Data.SqlClient"
Defensive patterns
Strategy: validation
Validate before calling
static void CheckStorageInvariant(AdoNetGrainStorageOptions o)
{
if (string.IsNullOrWhiteSpace(o.Invariant))
throw new InvalidOperationException("AdoNetGrainStorageOptions.Invariant must not be blank.");
} Prevention
- Avoid setting "Invariant": "" in config, which overrides the SQL Server default.
- Reference the invariant via AdoNetInvariants constants.
- Add a config test asserting Invariant is non-blank after binding.
When it happens
Trigger: ValidateConfiguration() runs with options.Invariant explicitly set to "" or null, overriding the DEFAULT_ADONET_INVARIANT (SqlServer) default. Also possible if options are deserialized from config that has an empty Invariant key overriding the default.
Common situations: An appsettings.json "Invariant": "" entry that wipes the default; deserializing options from a source missing the Invariant field with a null-coercing binder; explicitly setting Invariant = null in code.
Related errors
- Invalid {nameof(AdoNetGrainDirectoryOptions)} values for {na
- Invalid AdoNetGrainStorageOptions for AdoNetGrainStorage {na
- Invalid {nameof(AdoNetGrainStorageOptions)} values for {name
- Invalid {nameof(AdoNetGrainStorageOptions)} values for {name
- Invalid {nameof(AdoNetReminderTableOptions)} values for {nam
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/80e749e5c365c325.
Report an issue: GitHub.