Job for apache2.service failed because the control process exited with error code

Run sudo apache2ctl configtest (or sudo httpd -t on RHEL, Rocky and Alma). It names the file and line that broke, which the systemd message never does. Fix that line, then sudo systemctl reload apache2.

$ sudo apache2ctl configtest
AH00526: Syntax error on line 14 of /etc/apache2/sites-enabled/app.conf:
Invalid command 'ProxyPas', perhaps misspelled or defined by a module not included in the server configuration

That one line contains both common causes at once: a typo, or a directive belonging to a module that is not loaded.

Why the systemd message is useless here

The message is not an Apache error. systemd is reporting only that the process it launched returned a non-zero exit code. Apache parses its whole configuration before it binds a socket, writes the reason to stderr, and exits. systemd sees the integer and nothing else, so it prints its generic line and stops.

The reason went to the journal. These two commands are where it actually lives:

# the reason, in one line
sudo apache2ctl configtest

# the reason, with surrounding context
sudo journalctl -xeu apache2.service --no-pager | tail -40

What configtest will tell you

  1. Invalid command '...', perhaps misspelled or defined by a module not included: either a typo or a missing module. Check spelling first. If the spelling is right, enable the module: sudo a2enmod proxy_http then retry. This is the single most common cause on Ubuntu after copying a vhost from somewhere else.
  2. DocumentRoot [/var/www/app] does not exist: Apache refuses to start rather than serve a missing directory. Create it, or correct the path in the vhost.
  3. Could not open configuration file ...: No such file or directory: usually a dangling symlink in sites-enabled left behind after a vhost file was deleted. Clear it with sudo a2dissite app.
  4. SSLCertificateFile: file does not exist or is empty: almost always a Certbot renewal that moved or removed a lineage while the vhost still points at the old path. Run ls -l on the path in the error and check whether the symlink target still exists.
  5. AH00558: Could not reliably determine the server's fully qualified domain name: this one is a warning, not the failure. Set ServerName to silence it, but keep looking for the real error.

When configtest passes but the service still will not start

A clean configtest rules out syntax, module and path problems, because configtest parses the config, resolves includes and opens certificates. What it does not do is bind a socket. That leaves a short list:

  1. Port 80 or 443 is already taken. The usual culprit is nginx on a repurposed server, or a stale Apache process that survived a bad shutdown:
    sudo ss -tlnp | grep -E ':(80|443) '

    The journal shows (98)Address already in use: AH00072: make_sock: could not bind to address.

  2. SELinux is blocking a non-standard port. On RHEL, Rocky and Alma, a Listen 8085 fails until SELinux is told about it: sudo semanage port -a -t http_port_t -p tcp 8085.
  3. A stale PID file. If the journal mentions httpd.pid or a pre-existing PID, remove the file and start again.

Reading the exit code

systemctl status apache2 prints a status number that narrows things before you read a single log line. status=1/FAILURE means Apache ran and rejected its own configuration, which covers nearly every case here. status=137 means it was killed by SIGKILL and is usually the OOM killer rather than a config problem. The full table, which applies to any systemd unit, is in the nginx version of this error.

How to stop it happening again

Test before you apply, and reload rather than restart. configtest exits non-zero on a bad config, so chaining on && means a broken config never reaches the running server:

sudo apache2ctl configtest && sudo systemctl reload apache2

reload keeps existing workers serving traffic while the new config comes up, so a mistake costs nothing. restart tears the server down first, which is how a one-character typo becomes real downtime.

Related

Does this apply to httpd on RHEL as well as apache2 on Ubuntu?

Yes. The wording belongs to systemd, so the message is identical; only the names change. Use httpd -t instead of apache2ctl configtest, look at /etc/httpd/conf.d/ instead of sites-enabled, and remember that RHEL family systems have SELinux enabled by default, which adds the port and file-context failures described above.

configtest says Syntax OK but reload still does nothing

Then Apache is running and serving the old configuration. Confirm with systemctl is-active apache2. A reload only re-reads enabled sites, so check that your vhost is actually symlinked into sites-enabled with sudo a2ensite app. A file sitting in sites-available alone is never read.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *