"Job for nginx.service failed because the control process exited with error code": how to find the cause
Fix "Job for X.service failed because the control process exited with error code": read systemctl status and journalctl, test the config, and fix the usual causes.
by OhSudo ··
Not sure this is your cause?Find it step by step: Website down →
Part of a learning path:Linux: from zero to fixing a server
You start or restart a service and systemd answers:
$ sudo systemctl start nginxJob for nginx.service failed because the control process exited with error code.See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details.The message is the same for every service (nginx, Apache, PostgreSQL, your own app), and it only says that something failed. systemd ran a command to start the service, the command exited with an error, and systemd gave up. Why it failed is in the two places the message itself points to: systemctl status and the journal.
- systemctl start nginxruns
- ExecStartthe service's start commandfails(fails)
- Exited with an errorunit failed: see journalctl(breaks here)
TL;DR
systemctl status nginx --no-pager # state, exit status, last log linessudo journalctl -xeu nginx --no-pager # the full log of the failed startsudo nginx -t # nginx: test the config, shows file and lineThen fix what the log says, test again, and start the service.
1. Read the status
× nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled) Active: failed (Result: exit-code) since Sun 2026-11-01 09:12:40 UTC; 2min ago
Nov 01 09:12:40 ohsudo systemd[1]: Starting nginx.service - A high performance web server and a reverse proxy server...Nov 01 09:12:40 ohsudo nginx[702]: nginx: [emerg] unknown directive "servername" in /etc/nginx/sites-enabled/default:5Nov 01 09:12:40 ohsudo nginx[702]: nginx: configuration file /etc/nginx/nginx.conf test failedNov 01 09:12:40 ohsudo systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILUREThree things to look at:
Active: failed (Result: …)—exit-codemeans a command returned an error;signalmeans it was killed;start-limit-hitmeans systemd stopped trying (section 5).status=…on the “exited” line — the exit code. Codes above 200 come from systemd itself and have names (section 4).- The lines from the service itself (here
nginx[702]: …) — usually the real error, in the program’s own words.
systemctl status shows only the last few lines. If they are cut, or you need more, read the journal.
2. Read the journal
-u nginx limits it to this unit, -e jumps to the end, and -x adds explanations to systemd’s messages. Read from the bottom up to the first line that comes from the program, not from systemd[1]. With --since "10 min ago" you can skip older starts.
Some services also write to their own log file, and the most useful message may be only there: /var/log/nginx/error.log, /var/log/apache2/error.log (/var/log/httpd/ on RHEL), /var/log/postgresql/.
3. Test the configuration
Most of the time, the error is a typo in a config file someone just edited. Most daemons can check their own configuration without starting, and they tell you the file and the line:
nginx: [emerg] unknown directive "servername" in /etc/nginx/sites-enabled/default:5nginx: configuration file /etc/nginx/nginx.conf test failedFix the line, test again, and start the service only when the test passes:
sudo sed -i 's/servername/server_name/' /etc/nginx/sites-enabled/defaultsudo nginx -t && sudo systemctl start nginxThe same idea for other services:
| Service | Config test |
|---|---|
| nginx | sudo nginx -t |
| Apache | sudo apachectl configtest |
| OpenSSH | sudo sshd -t |
| HAProxy | sudo haproxy -c -f /etc/haproxy/haproxy.cfg |
| BIND | sudo named-checkconf |
| PHP-FPM | sudo php-fpm8.3 -t (the version is part of the name on Debian/Ubuntu; php-fpm -t on RHEL) |
Warning
reload vs. restart with a broken config. systemctl reload nginx tests the new config first, and if it fails, nginx keeps running with the old one. systemctl restart nginx stops nginx first — if the new config is broken, it doesn’t come back, and your site is down. Test before you restart: sudo nginx -t && sudo systemctl restart nginx.
4. The usual causes
The port is taken. bind() to 0.0.0.0:80 failed (98: Address already in use) — another program already listens there. See find who is using port 80.
A file is missing or can’t be read. A certificate, a key, a log folder, a socket path:
nginx: [emerg] cannot load certificate "/etc/ssl/certs/example.com.crt": BIO_new_file() failed (… No such file or directory …)Check the path from the message with ls -l, and check that the service’s user can read it. On RHEL-family systems, a file with the wrong SELinux label gives Permission denied even with correct permissions: sudo restorecon -v <file>.
The program can’t be started at all. For your own services, the exit status has a name that tells you which step failed:
| Exit status | Meaning | Check |
|---|---|---|
203/EXEC |
The program in ExecStart= doesn’t exist or isn’t executable |
The path in systemctl cat <service>, then ls -l on it |
217/USER |
The user in User= doesn’t exist |
id <user> |
200/CHDIR |
WorkingDirectory= doesn’t exist |
ls -ld <folder> |
1/FAILURE |
The program itself exited with an error | Its own lines in the journal |
You edited the unit file but systemd still uses the old one. systemd warns you about it:
Warning: The unit file, source configuration file or drop-ins of myapp.service changed on disk. Run 'systemctl daemon-reload' to reload units.Run sudo systemctl daemon-reload, then start the service again.
5. “Start request repeated too quickly”
myapp.service: Start request repeated too quickly.myapp.service: Failed with result 'start-limit-hit'.A service that crashes and restarts in a loop is stopped after a few tries (by default, 5 starts in 10 seconds). This isn’t the cause, only a symptom — find the real error further up in the journal. After you fix it, clear the counter and start again:
sudo systemctl reset-failed myappsudo systemctl start myappShell, we have a problem!
Similar, but different: Failed to start nginx.service: Unit nginx.service not found. means the service isn’t installed, or its name is different (apache2 on Debian/Ubuntu, httpd on RHEL; ssh vs. sshd). systemctl list-unit-files | grep <name> shows the real name. Interactive authentication required means you forgot sudo. System has not been booted with systemd means systemd isn’t running there at all: see that article. On RHEL, a service that fails with Permission denied while its files look fine is often SELinux. For the commands around this, see the systemctl and journalctl Cheat Sheet. To practice this safely, try the lesson Nginx won’t start.
$ ./practice.sh
Practice this in the terminal
Open the Terminal Playground with this article’s scenario loaded. It is safe and runs in your browser.
Found this useful? Share it.
Found a mistake? Let us know at contact@ohsudo.com.