laravel/framework · error · InvalidArgumentException
Timeout must be greater than zero.
Error message
Timeout must be greater than zero.
What it means
Thrown by timeout() when the supplied integer of seconds is <= 0 (and not null). The setter configures the per-query execution timeout; zero or negative durations are meaningless for SQL statement timeouts and would either no-op or be rejected by the driver. Passing null explicitly disables the timeout and is allowed.
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 bd6b5437e6)
Solutions
- Pass a positive integer: `->timeout(30)`.
- Pass null to disable: `->timeout(null)`.
- Guard config-driven values: `->timeout($cfg > 0 ? $cfg : null)`.
- Validate before calling: `if ($seconds !== null && $seconds <= 0) abort(400, 'bad timeout');`.
Example fix
// before
$query->timeout((int) config('app.query_timeout', 0))->get();
// when default is 0 => Timeout must be greater than zero.
// after
$secs = (int) config('app.query_timeout', 0);
$query->timeout($secs > 0 ? $secs : null)->get(); Defensive patterns
Strategy: validation
Validate before calling
if ($seconds !== null && $seconds <= 0) {
$seconds = null; // or throw
}
$query->timeout($seconds); Type guard
function isValidTimeout(?int $s): bool
{
return $s === null || $s > 0;
} Try / catch
// Validate before calling; catching an InvalidArgumentException here adds noise.
Prevention
- Treat 0 as 'no timeout' by mapping to null at the config layer.
- Bound any adaptive timeout from below: max(1, $computed).
- Unit-test the timeout helper with edge values (0, -1, null).
When it happens
Trigger: `->timeout(0)`, `->timeout(-1)`. Computing timeout from a config value that defaults to 0. Subtracting a large offset that goes negative: `->timeout($budget - $elapsed)`.
Common situations: Config-driven timeouts where the env var is unset and casts to 0; adaptive timeout budgets that go negative under load; tests passing 0 expecting 'no timeout' semantics.
Related errors
- A subquery must be a query builder instance, a Closure, or a
- Nested arrays may not be passed to whereIn method.
- The number of columns must match the number of values
- Order direction must be a SortDirection, "asc" or "desc".
- The unique columns must not be empty.
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/e84c1e5d93983114.json.
Report an issue: GitHub.