PHP: How do you get error messages to display?

You call your script and get a blank page. No message, no hint, nothing. That is one of the most frustrating moments in PHP development, and the fix consists of exactly two settings.

The two settings

To get an error message to show up, both settings have to be right:

<?php
  ini_set('display_errors', '1');
  error_reporting(E_ALL);
?>

display_errors decides whether anything is output at all. error_reporting decides which messages those are. If you only set one of the two, you still see nothing, or only part of it.

What the blank page actually is

This is worth looking at closely. Take a script with two problems: an access to an array key that is not set, and a call to a method that does not exist.

With display_errors=Off, the typical setting on a production system:

Port: (nicht gesetzt)
Zugriff ohne ??:
(exit code: 255)

And with display_errors=On and error_reporting=E_ALL:

Port: (nicht gesetzt)
Zugriff ohne ??:
Warning: Undefined array key "port" in /buggy.php on line 8

Fatal error: Uncaught Error: Call to undefined method stdClass::machWas() in /buggy.php:11
Stack trace:
#0 {main}
  thrown in /buggy.php on line 11
(exit code: 255)

The decisive part is the last line: in both cases the exit code is 255. The script therefore fails in exactly the same way. The blank page is not a different state from the error message, it is the same state without any feedback. display_errors does not repair anything, it only makes visible what happens anyway.

error_reporting filters independently

If you turn on display_errors but forget error_reporting, you may still see only part of the picture. With E_ALL & ~E_WARNING the same script looks like this:

Port: (nicht gesetzt)
Zugriff ohne ??:

Fatal error: Uncaught Error: Call to undefined method stdClass::machWas() in /buggy.php:11
Stack trace:
#0 {main}
  thrown in /buggy.php on line 11
(exit code: 255)

The warning about the array key has gone, the fatal error has stayed. That is exactly why the two settings belong together.

On production it belongs in the log

display_errors=On is a bad idea on a publicly reachable server. Error messages give away file paths, class names and sometimes credentials. The right setting there is:

display_errors = Off
log_errors = On
error_log = /path/to/your/error.log

The same messages then land in a file, complete with a timestamp:

[28-Aug-2026 19:59:46 UTC] PHP Warning:  Undefined array key "port" in /buggy.php on line 8
[28-Aug-2026 19:59:46 UTC] PHP Fatal error:  Uncaught Error: Call to undefined method stdClass::machWas() in /buggy.php:11
Stack trace:
#0 {main}
  thrown in /buggy.php on line 11

Why ini_set() sometimes does not help

A common stumbling block: with a parse error, ini_set() is of no use. A syntax error is detected before even one line of your script runs, so the line that is supposed to turn on display_errors never executes.

For that case you have to set the option in php.ini itself — or, during development, pass it on the command line:

user@pc:~$ php -d display_errors=1 -d error_reporting=E_ALL script.php

Which php.ini applies anyway?

The second big source of confusion. You edit a php.ini and nothing happens, because a completely different one is being loaded. You find out like this:

user@pc:~$ php --ini

In the official PHP Docker image that comes with a surprise:

Configuration File (php.ini) Path: "/usr/local/etc/php"
Loaded Configuration File:         (none)
Scan for additional .ini files in: "/usr/local/etc/php/conf.d"

Loaded Configuration File: (none) — the image loads no php.ini at all. All that sits there are the templates php.ini-development and php.ini-production, one of which you have to copy into place. If you edit a php.ini inside a container and wonder why nothing changes, this is usually the reason.

Also bear in mind that PHP-FPM and the command line can use different configurations. So if you see nothing through the web server but everything on the command line, go and look at the FPM configuration.

Summary

  • display_errors controls whether, error_reporting controls what. Set both.
  • The blank page is the same failure as the message, just without any output.
  • On production: display_errors=Off and log_errors=On.
  • For parse errors only php.ini or -d on the command line helps.
  • php --ini tells you which configuration is actually being loaded.

About Netcup (advertisement)

The German host Netcup offers, among other things, affordable and powerful web hosting packages, KVM-based root servers and dedicated servers. With our voucher codes you can save even more (6€ off your first order, 30% off all KVM-based root servers, ...).