dotnet/efcore · error · InvalidOperationException
The specified 'CommandTimeout' value '{value}' is not valid.
Error message
The specified 'CommandTimeout' value '{value}' is not valid. It must be a positive number. What it means
Thrown by RelationalOptionsExtension.WithCommandTimeout(int?) at line 167-169 when the supplied timeout is a negative integer. EF defines 0 as 'no timeout' and any positive value as seconds; negative values are meaningless. The guard is `commandTimeout is < 0`.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs:169
}
/// <summary>
/// The command timeout, or <see langword="null" /> if none has been set.
/// </summary>
public virtual int? CommandTimeout
=> _commandTimeout;
/// <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="commandTimeout">The option to change.</param>
/// <returns>A new instance with the option changed.</returns>
public virtual RelationalOptionsExtension WithCommandTimeout(int? commandTimeout)
{
if (commandTimeout is < 0)
{
throw new InvalidOperationException(RelationalStrings.InvalidCommandTimeout(commandTimeout));
}
var clone = Clone();
clone._commandTimeout = commandTimeout;
return clone;
}
/// <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.View on GitHub (pinned to dbf9771522)
Solutions
- Set CommandTimeout to 0 for unlimited/no timeout, or to a positive number of seconds.
- Validate the config value before passing it: use Math.Max(0, configuredValue).
- Check your appsettings.json / environment variable for a negative timeout value and correct it.
Example fix
// before optionsBuilder.UseSqlServer(connStr, sql => sql.CommandTimeout(-1)); // after: 0 means no timeout optionsBuilder.UseSqlServer(connStr, sql => sql.CommandTimeout(0));
Defensive patterns
Strategy: validation
Validate before calling
var timeout = configuration.GetValue<int?>("CommandTimeout") ?? 30;
if (timeout < 0) throw new ArgumentOutOfRangeException(nameof(timeout), "CommandTimeout must be >= 0");
optionsBuilder.UseSqlServer(connStr, sql => sql.CommandTimeout(timeout)); Try / catch
// Wrap external configuration reads
try { optionsBuilder.UseSqlServer(connStr, sql => sql.CommandTimeout(timeoutFromConfig)); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CommandTimeout"))
{ logger.LogWarning(ex, "Invalid CommandTimeout in config, falling back to default"); } Prevention
- Validate timeout values from config before passing to EF (>= 0).
- Use 0 for infinite timeout, not -1.
- Centralize all EF options configuration in one validated helper method.
When it happens
Trigger: Calling optionsBuilder.UseSqlServer(connStr, sql => sql.CommandTimeout(-1)) or directly setting CommandTimeout to any value less than 0. Also happens when the timeout is read from configuration/appsettings with a misconfigured negative number.
Common situations: Reading CommandTimeout from a config file or environment variable that is misconfigured, or passing -1 intending 'infinite' (the correct infinite value is 0 in EF Core). Off-by-one errors in timeout calculation code.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Invalid number of index sort order values: {numValues} value
- The number argument cannot be a negative number.
- The value '{value}' provided for argument '{argumentName}' m
- Timeout must be greater than or equal to zero. Provided time
- The specified 'MaxBatchSize' value '{value}' is not valid. I
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/1a7458cf94f2ccf6.
Report an issue: GitHub.