laravel/framework · error · InvalidArgumentException
Timeout must be greater than zero.
Error message
Timeout must be greater than zero.
What it means
timeout() sets a per-query execution timeout. A null argument means 'no timeout', and any positive integer is accepted, but a non-positive integer (0 or negative) is meaningless as a timeout and is rejected with InvalidArgumentException before it could produce surprising SQL.
Solutions
- Pass null to explicitly disable the timeout instead of 0.
- Coerce incoming config: $seconds = $cfg > 0 ? $cfg : null.
- Fix the config/env value to a positive integer.
Example fix
// before
->timeout(config('database.options.timeout', 0))
// after
->timeout(config('database.options.timeout')) // null when unset Defensive patterns
Strategy: validation
Validate before calling
$seconds = $cfg > 0 ? (int) $cfg : null; $query->timeout($seconds);
Prevention
- Use null to mean 'no timeout', never 0.
- Coerce config values: keep only positive integers, else null.
- Document the meaning of null vs positive int in the config file.
When it happens
Trigger: ->timeout(0), ->timeout(-5), or passing a computed value (e.g. config('query.timeout') configured to 0) when the engine cannot honour a zero/negative duration.
Common situations: Reading the timeout from config/env and forgetting to default it; passing a configurable value that an operator set to 0 thinking it disables the limit (use null instead); math that yields a negative number.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- A subquery must be a query builder instance, a Closure, or…
- $count records were found.
- Illegal operator and value combination.
- Invalid binding type
- Nested arrays may not be passed to whereIn method.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/e84c1e5d93983114.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Query/Builder.php:3381
* @return $this
*/
public function sharedLock()
{
return $this->lock(false);
}
/**
* Set a query execution timeout in seconds.
*
* @param int|null $seconds
* @return $this
*
* @throws InvalidArgumentException
*/
public function timeout(?int $seconds): static
{
if ($seconds !== null && $seconds <= 0) {
throw new InvalidArgumentException('Timeout must be greater than zero.');
}
$this->timeout = $seconds;
return $this;
}
/**
* Register a closure to be invoked before the query is executed.
*
* @return $this
*/
public function beforeQuery(callable $callback)
{
$this->beforeQueryCallbacks[] = $callback;
return $this;
}View on GitHub (pinned to e0f6eb3518)