[Laravel + Sail] Bug: gzdecode(): data error
Description:
When trying to fetch profiles for a Laravel application running with Sail (Runtime Version 8.3) something is going wrong with when trying to decompress the cachegrind profile archive in XdebugDataSource.
Steps to reproduce:
# create a new project
laravel new --no-interaction -- test-case
cd ./test-case
# Add clockwork
composer require --dev itsgoingd/clockwork
# install sail
php artisan sail:install --with=none --php=8.3
# Add custom xdebug configuration
mkdir ./.docker
{
echo '[xdebug]'
echo 'xdebug.mode=${XDEBUG_MODE}'
echo 'xdebug.start_with_request = trigger'
echo 'xdebug.profiler_output_name = cachegrind.out.%u.%r'
} >> ./.docker/20-xdebug.ini
# Add custom xdebug config to mounted volumes
awk 'NR==22{print " - './.docker/20-xdebug.ini:/etc/php/8.3/conf.d/20-xdebug.ini'"}1' ./docker-compose.yml > ./tmp && mv ./tmp ./docker-compose.yml
# Configure SAIL_XDEBUG_MODE=profile
echo "SAIL_XDEBUG_MODE=profile" >> .env
./vendor/bin/sail up -d
Then open up clockwork and in another tab localhost.
Enable the profiler for / and reload to capture the request using profiling.
The error should show up in storage/logs/laravel.log as well as in your browser's dev tools.
Stack Trace:
[2025-08-20 10:24:10] local.ERROR: gzdecode(): data error {"exception":"[object] (ErrorException(code: 0): gzdecode(): data error at /var/www/html/vendor/itsgoingd/clockwork/Clockwork/DataSource/XdebugDataSource.php:25)
[stacktrace]
#0 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(258): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}()
#2 /var/www/html/vendor/itsgoingd/clockwork/Clockwork/DataSource/XdebugDataSource.php(25): gzdecode()
#3 /var/www/html/vendor/itsgoingd/clockwork/Clockwork/Clockwork.php(120): Clockwork\\DataSource\\XdebugDataSource->extend()
#4 /var/www/html/vendor/itsgoingd/clockwork/Clockwork/Support/Laravel/ClockworkSupport.php(67): Clockwork\\Clockwork->extendRequest()
#5 /var/www/html/vendor/itsgoingd/clockwork/Clockwork/Support/Laravel/ClockworkSupport.php(87): Clockwork\\Support\\Laravel\\ClockworkSupport->getData()
#6 /var/www/html/vendor/itsgoingd/clockwork/Clockwork/Support/Laravel/ClockworkController.php(40): Clockwork\\Support\\Laravel\\ClockworkSupport->getExtendedData()
#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): Clockwork\\Support\\Laravel\\ClockworkController->getExtendedData()
#8 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction()
#9 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(265): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#10 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(211): Illuminate\\Routing\\Route->runController()
#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(822): Illuminate\\Routing\\Route->run()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(821): Illuminate\\Pipeline\\Pipeline->then()
#15 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(800): Illuminate\\Routing\\Router->runRouteWithinStack()
#16 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(764): Illuminate\\Routing\\Router->runRoute()
#17 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(753): Illuminate\\Routing\\Router->dispatchToRoute()
#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\\Routing\\Router->dispatch()
#19 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#21 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#23 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#25 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#27 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\\Http\\Middleware\\ValidatePostSize->handle()
#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(109): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#29 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(48): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#31 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\\Http\\Middleware\\HandleCors->handle()
#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#33 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/InvokeDeferredCallbacks.php(22): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\\Foundation\\Http\\Middleware\\InvokeDeferredCallbacks->handle()
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePathEncoding.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(219): Illuminate\\Http\\Middleware\\ValidatePathEncoding->handle()
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\\Pipeline\\Pipeline->then()
#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1219): Illuminate\\Foundation\\Http\\Kernel->handle()
#42 /var/www/html/public/index.php(20): Illuminate\\Foundation\\Application->handleRequest()
#43 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/resources/server.php(23): require_once('...')
#44 {main}
"}
What's interesting is, that the gz archive seems to be in tact.
When you open up a shell using ./vendor/bin/sail bash, then run an interactive PHP session using php -a and manually perform what the XdebugDataSource does:
$archiveData = file_get_contents('/tmp/cachegrind.out.15.gz');
$profileData = gzdecode($archiveData);
echo $profileData;
It just works as intended.
LMK if you need further information and thanks for the awesome tool!
Hey, I see you are overriding xdebug.profiler_output_name in your Docker setup, can you double-check if this setting is applied with a simple phpinfo?
Thank you for your reply.
Two interesting observations:
-
xdebug.profiler_output_nameis applied correctlysail@5aab98a2cdc3:/var/www/html$ php -i|grep profiler_output_name xdebug.profiler_output_name => cachegrind.out.%p => cachegrind.out.%p - Simply running the script I've provided to bootstrap the test-case does work now without any issues.
I'll investigate the issue in my actual project and come back to you after upgrading some dependencies. Maybe it has been solved, maybe it is related to octane. I don't know yet.