Showing PHP warnings and fatal errors makes debugging faster when a request fails, an include breaks, or a runtime change stops the application from starting. Hiding that same output matters on internet-facing systems because visible diagnostics can leak stack traces, filesystem paths, SQL fragments, and other internal details that belong in operator tooling instead of the response body.
PHP separates error generation from error display. error_reporting defines which severities are raised, display_errors and display_startup_errors control whether the client sees them, and log_errors keeps the same events available to operators. On PHP-FPM hosts, the final value can also be changed after php.ini by pool-level php_value[] or php_admin_value[] directives, FastCGI PHP_VALUE or PHP_ADMIN_VALUE headers, or a local .user.ini file.
Examples below use the packaged PHP-FPM layout common on current Ubuntu or Debian systems. Replace the sample binary name, service unit, and path with the branch that actually serves the application, keep log_errors enabled when output is hidden, and validate the configuration before reloading so a display-setting change does not become an outage.
Steps to show or suppress warning and error messages in PHP:
- Check which PHP-FPM configuration file and baseline error-display values are loaded before changing the runtime profile.
$ php-fpm8.3 -i | grep -E '^(Loaded Configuration File|display_errors =>|display_startup_errors =>|error_reporting =>|log_errors =>)' Loaded Configuration File => /etc/php/8.3/fpm/php.ini display_errors => Off => Off display_startup_errors => Off => Off error_reporting => 32767 => 32767 log_errors => On => On
Use the binary that matches the deployed runtime. php --ini reports only the CLI configuration, which is often different from PHP-FPM or an Apache module.
Related: How to find PHP configuration files
- Back up the active php.ini file before changing the display directives.
$ sudo cp /etc/php/8.3/fpm/php.ini /etc/php/8.3/fpm/php.ini.bak-$(date +%Y%m%d%H%M%S)
- Open the active PHP-FPM php.ini file in a text editor.
$ sudo vi /etc/php/8.3/fpm/php.ini
Replace the sample path with the file reported in the first step when the runtime uses a different PHP branch, layout, or SAPI.
Related: How to find PHP configuration files
- Set the directives for a temporary debugging profile when warnings, notices, and startup failures must be visible in the response.
display_errors = On display_startup_errors = On error_reporting = E_ALL log_errors = On
error_reporting = -1 is equivalent to E_ALL and keeps future error levels included as well.
Do not leave display_errors = On enabled on a public application after the debugging session is complete.
- Set the directives for a production profile when the response must stay clean while operators still keep the diagnostics.
display_errors = Off display_startup_errors = Off error_reporting = E_ALL log_errors = On
Keeping error_reporting = E_ALL with log_errors = On hides the warning from the client without discarding the event from logs.
Setting error_reporting = 0 suppresses useful diagnostics instead of only hiding them from the response.
- Run a PHP-FPM configuration test before reloading the service.
$ sudo php-fpm8.3 -tt [25-Mar-2026 22:59:16] NOTICE: configuration file /etc/php/8.3/fpm/php-fpm.conf test is successful
Use php-fpm -tt on systems that provide an unversioned binary. The -tt option prints the resolved PHP-FPM configuration as well as the final syntax result.
Do not reload the service until the configuration test succeeds.
- Reload the PHP-FPM service so the updated display directives apply to new requests.
$ sudo systemctl reload php8.3-fpm
When PHP runs as an Apache module, reload the web server instead, such as sudo systemctl reload apache2 or sudo systemctl reload httpd. On .user.ini-based deployments, the new value normally appears after the user_ini.cache_ttl interval rather than a service reload.
- Create a short probe script inside the document root served by the edited runtime.
$ sudo tee /var/www/example.com/public/php-warning-check.php >/dev/null <<'PHP' <?php trigger_error('display probe', E_USER_WARNING); echo "probe complete", PHP_EOL; PHPReplace /var/www/example.com/public with the real document root for the site or pool that uses the edited runtime.
Remove the probe file after the visible or hidden warning output is confirmed so a diagnostic endpoint is not left exposed.
- Request the probe through the same host and path that reaches the edited runtime.
$ curl -s http://example.com/php-warning-check.php Warning: display probe in /var/www/example.com/public/php-warning-check.php on line 2 probe complete
With the debugging profile, the warning should appear before probe complete. With the production profile, the same request should return only probe complete while the warning is still logged. If the site is only reachable through HTTPS, a local vhost name, or an internal reverse proxy, use that exact URL instead of the example host.
- Remove the temporary probe script after the result matches the selected profile.
$ sudo rm /var/www/example.com/public/php-warning-check.php
- Check for PHP-FPM pool or web-server overrides when the probe result still does not match the selected profile.
$ sudo grep -REn 'php_(admin_)?(flag|value)\[(display_errors|display_startup_errors|error_reporting|log_errors|error_log)\]|PHP_(ADMIN_)?VALUE' /etc/php/8.3/fpm/pool.d /etc/php-fpm.d /etc/apache2 /etc/httpd /etc/nginx 2>/dev/null /etc/php/8.3/fpm/pool.d/www.conf:490:php_admin_flag[display_errors] = off
PHP-FPM pool files can override the global php.ini with php_flag[], php_value[], php_admin_flag[], or php_admin_value[]. FastCGI PHP_VALUE and PHP_ADMIN_VALUE parameters can do the same in the web-server configuration.
Settings forced with php_admin_value[] or php_admin_flag[] cannot be changed later with ini_set().
- Search the application tree for per-directory .user.ini files when the runtime uses CGI or FastCGI and the probe still does not match the expected profile.
$ find /var/www/example.com -name .user.ini -print /var/www/example.com/public/.user.ini
These files are ignored when PHP runs as an Apache module. On CGI and FastCGI deployments, changes are re-read on the user_ini.cache_ttl interval instead of immediately.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
