dotnet/efcore · error · InvalidOperationException
The specified 'MaxBatchSize' value
Error message
The specified 'MaxBatchSize' value '{value}' is not valid. It must be a positive number. What it means
RelationalOptionsExtension.WithMaxBatchSize requires the value be null (unset) or strictly greater than zero; 0 and negatives are rejected. This bounds the number of statements grouped into one multi-statement command during SaveChanges.
Solutions
- Pass a positive int (>= 1) for an explicit cap, or leave unset / pass null to use the provider default.
- Validate config: treat 0/negative as 'unset' (null).
- To disable batching, set MaxBatchSize to 1, not 0.
Example fix
// before optionsBuilder.UseSqlServer(conn).MaxBatchSize(0); // after optionsBuilder.UseSqlServer(conn).MaxBatchSize(1); // or omit to use default
Defensive patterns
Strategy: validation
Validate before calling
static int? SafeMaxBatchSize(string? raw)
=> int.TryParse(raw, out var v) && v > 0 ? v : (int?)null; Type guard
static bool IsValidMaxBatchSize(int? value) => value is null || value > 0;
Prevention
- Do not pass 0 to mean 'disabled' — use 1 to effectively disable multi-statement batching, or leave unset.
- Validate config before applying; treat 0/negative as unset.
- Keep options construction in one place.
When it happens
Trigger: Calling optionsBuilder.MaxBatchSize(0) or .MaxBatchSize(-3); computing MaxBatchSize from config that can resolve to 0.
Common situations: Defaulting to 0 to mean 'disabled'; mis-parsed config; tests that pass 0 expecting batching off (you should leave it unset instead).
Related errors
- The specified 'MinBatchSize' value
- The specified 'CommandTimeout' value
- Multiple relational database provider configurations found…
- No relational database providers are configured. Configure…
- Relational-specific methods can only be used when the…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/885306632baf1e75.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs:197
/// <summary>
/// The maximum number of statements that will be included in commands sent to the database
/// during <see cref="DbContext.SaveChanges()" /> or <see langword="null" /> if none has been set.
/// </summary>
public virtual int? MaxBatchSize
=> _maxBatchSize;
/// <summary>
/// Creates a new instance with all options the same as for this instance, but with the given option changed.
/// It is unusual to call this method directly. Instead use <see cref="DbContextOptionsBuilder" />.
/// </summary>
/// <param name="maxBatchSize">The option to change.</param>
/// <returns>A new instance with the option changed.</returns>
public virtual RelationalOptionsExtension WithMaxBatchSize(int? maxBatchSize)
{
if (maxBatchSize.HasValue
&& maxBatchSize <= 0)
{
throw new InvalidOperationException(RelationalStrings.InvalidMaxBatchSize(maxBatchSize));
}
var clone = Clone();
clone._maxBatchSize = maxBatchSize;
return clone;
}
/// <summary>
/// The minimum number of statements that are needed for a multi-statement command sent to the database
/// during <see cref="DbContext.SaveChanges()" /> or <see langword="null" /> if none has been set.
/// </summary>
public virtual int? MinBatchSize
=> _minBatchSize;
/// <summary>
/// Creates a new instance with all options the same as for this instance, but with the given option changed.View on GitHub (pinned to 3a2006ef56)