How to Fix Exposed Laravel Ignition Error Pages
Laravel Ignition error pages are visible in production, leaking stack traces and environment details. Learn how to disable them.
Laravel Ignition replaced Whoops as the default error page renderer starting in Laravel 6, developed by Spatie. It provides developers with contextual solutions alongside stack traces — a genuinely useful development tool that significantly speeds up debugging. The problem is that Ignition's design assumes it will never be seen by end users or in a production context.
Beyond information disclosure, Ignition has a significant security history. In January 2021, a remote code execution vulnerability (CVE-2021-3129) was discovered in versions prior to 2.5.2. The flaw allowed an unauthenticated attacker to execute arbitrary PHP code through Ignition's debug endpoint that processed Phar deserialization payloads. Public proof-of-concept exploits circulated within hours of disclosure, and servers running vulnerable versions with debug mode on were compromised at scale. This remains one of the most impactful Laravel vulnerabilities ever published.
Even without RCE, the information Ignition exposes in an error page is extensive. Each page shows a source code file browser, the complete stack trace, all environment variables (including APP_KEY, database credentials, and API keys), PHP and Laravel versions, installed packages, database connection details, and recent log entries. Ignition pages have been indexed by Google and cached by internet archive services. This level of detail gives an attacker a complete blueprint of your application's internals, making every subsequent attack faster and more precisely targeted.
The Problem
Exposed Ignition error pages display detailed stack traces, source code snippets, environment variables, and request data to anyone who triggers an error on your site. Ignition is Laravel's default error page handler during development, and when it appears in production it provides attackers with file paths, database credentials, package versions, and application architecture details.
How to Fix
-
1
Disable debug mode in production
Ignition only shows detailed error pages when APP_DEBUG is true. Set in your production .env:APP_DEBUG=false APP_ENV=productionThen clear and rebuild the cache:
php artisan config:clear php artisan config:cache -
2
Remove Ignition from production if not needed
Move Ignition to dev-only dependencies:
composer remove spatie/laravel-ignition composer require spatie/laravel-ignition --devWhen deploying with --no-dev flag, Ignition will not be installed:
composer install --no-dev --optimize-autoloader -
3
Create custom error pages
Create Blade templates for common HTTP errors so users see branded pages:
resources/views/errors/404.blade.php:
<x-layouts.app> <div class="flex items-center justify-center min-h-screen"> <div class="text-center"> <h1 class="text-6xl font-bold text-gray-300">404</h1> <p class="text-xl text-gray-600 mt-4">Page not found</p> <a href="/" class="mt-6 inline-block text-blue-600 hover:underline">Go home</a> </div> </div> </x-layouts.app>Create similar pages for 500.blade.php and 503.blade.php.
-
4
Configure error reporting to an external service
Replace visible error pages with proper error tracking. Install Sentry or Flare:
composer require sentry/sentry-laravel php artisan sentry:publishAdd to your .env:
SENTRY_LARAVEL_DSN=your-sentry-dsnThis captures all errors with full context without exposing details to users.
How to Verify
Trigger a 500 error on your production site by visiting a broken route or temporarily throwing an exception. You should see your custom error page or a generic server error, not the Ignition debug screen. Test with:
curl -s https://yourdomain.com/non-existent-route | grep -i "ignition\|whoops\|stack trace"
This should return no matches.
Prevention
Deploy with composer install --no-dev to exclude debug packages. Add APP_DEBUG=false verification to your deployment pipeline. Use StackShield to continuously verify that Ignition pages are not exposed after deployments or configuration changes.
Frequently Asked Questions
What is the difference between Ignition and Whoops?
Ignition replaced Whoops as Laravel's default error page handler starting in Laravel 6. Ignition provides more features like solution suggestions and a stack trace viewer. Both expose the same critical information (environment variables, source code, queries) when visible in production.
Can Ignition be exploited beyond just information disclosure?
Yes. Older versions of Ignition (before 2.5.2) had a remote code execution vulnerability (CVE-2021-3129) that allowed attackers to execute arbitrary code through the Ignition debug endpoint. Always keep Ignition updated and never expose it in production.
How do I track errors properly without relying on Ignition in production?
Configure an external error tracking service such as Sentry, Flare (Laravel-specific), or Bugsnag. These tools capture exceptions with full stack traces, environment context, and user information — but store them securely in your account rather than exposing them publicly. Flare integrates natively with Laravel and provides Ignition-style solution hints inside your private dashboard.
Can I show a custom error page for all errors, including 500 errors?
Yes. With APP_DEBUG=false, Laravel automatically renders Blade templates from resources/views/errors/ for each HTTP status code. Create 404.blade.php, 500.blade.php, and 503.blade.php extending your application layout. For exceptions that don't produce an HTTP response (uncaught exceptions), Laravel logs them and shows the 500 template.
Is Ignition 3.x (used in Laravel 11+) safer than older versions?
Ignition 3.x patched the CVE-2021-3129 RCE vulnerability and is actively maintained. However, the information disclosure risk remains the same in any version — it still shows your full environment and source code when debug mode is on. The core rule doesn't change: Ignition should never be visible in production regardless of version.
Related Guides
Laravel Debug Mode in Production: How to Disable APP_DEBUG and Stop Leaking Secrets
APP_DEBUG=true in production exposes stack traces, environment variables, and database credentials to anyone who triggers an error. Here is how to disable it safely and verify the fix.
How to Fix an Exposed Laravel Telescope Dashboard
Your Laravel Telescope dashboard is publicly accessible in production, exposing requests, queries, and application data. Secure it now.
Laravel .env File Exposed: How to Block Public Access and Rotate Leaked Credentials
Your Laravel .env file is publicly accessible, leaking database credentials, APP_KEY, and API keys. Block it in Apache and Nginx, then rotate every compromised secret.
Is your Laravel app exposed right now?
34% of Laravel apps we scan have at least one critical issue. Most teams don't find out until something breaks. Our free scan checks your live application in under 60 seconds.