laravel/framework · error · Exception
Dump execution exceeded maximum depth of 30.
Error message
Dump execution exceeded maximum depth of 30.
What it means
MySqlSchemaState::executeDumpProcess recursively retries the mysqldump/mysql shell command when specific known error phrases appear in the failure message ('column-statistics' / 'column_statistics' and 'set-gtid-purged'), each retry stripping the offending flag and incrementing $depth. The depth>30 check is a safety net that converts a runaway recursion into a clear Exception. In practice only two retry conditions exist, so reaching depth 30 indicates the retry path is matching repeatedly without resolving — a sign the underlying process error keeps re-appearing after each flag is stripped.
Solutions
- Inspect the actual ProcessFailedException message from the inner catch (enable verbose artisan output / check logs) to see which error string is recurring.
- Pin a mysqldump client version that matches the server (8.0 client against 8.0 server, or MariaDB against MariaDB) to avoid the column-statistics mismatch entirely.
- If you customize the dump command via the schema state or connection config, ensure it does not re-append --column-statistics=0 or --set-gtid-purged after the retry strips them.
- Set config('database.connections.mysql.dump.column_statistics', false) (Laravel's db config) or upgrade past the Laravel version whose default flags conflict with your client.
Example fix
// before (config/database.php — client keeps adding column-statistics)
'mysql' => [ /* defaults */ ],
// after (explicitly disable the offending option)
'mysql' => [
'driver' => 'mysql',
'dump' => [
'use_column_statistics' => false,
],
// ...
], Defensive patterns
Strategy: try-catch
Validate before calling
// verify the mysqldump client version and the configured dump options before dumping $version = DB::connection()->getPdo()->getAttribute(PDO::ATTR_CLIENT_VERSION); // prefer disabling the flag at config level rather than relying on the retry path
Try / catch
use Illuminate\Database\Schema\MySqlSchemaState;
use Symfony\Component\Process\Exception\ProcessFailedException;
try {
Artisan::call('schema:dump');
} catch (\Throwable $e) {
if (str_contains($e->getMessage(), 'maximum depth of 30')) {
// log inner ProcessFailedException details and align client/server versions
report($e);
} else {
throw $e;
}
} Prevention
- Pin the mysqldump client version to match the server major version.
- Set database.connections.mysql.dump options explicitly in config rather than relying on Laravel's defaults.
- Inspect verbose artisan output when schema:dump fails to see the underlying ProcessFailedException.
When it happens
Trigger: Calling Schema::dump() / the migrate:fresh --seed path that triggers MySqlSchemaState (e.g. php artisan schema:dump or migration loading), where mustRun() keeps failing with one of the retry-triggering error strings on every recursion, e.g. a custom dump command template that re-adds the flags or a shell environment that rewrites the command line.
Common situations: Mismatched mysqldump client vs server versions repeatedly emitting 'column-statistics' errors; a configured dump binary path or process factory that injects --column-statistics back in after the grammar strips it; corrupted/looping shell quoting that breaks flag removal.
Related errors
- This database driver requires a type, see the virtualAs /…
- Index [ ] does not exist.
- Schema dumping is not supported when using SQL Server.
- SQLite does not support altering primary keys.
- The database driver in use does not support spatial indexes.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/cfc866800f4b11b1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/MySqlSchemaState.php:182
View on GitHub (pinned to e0f6eb3518)