systemd service fails with exit code 1: missing env var fix
Your systemd service exits with code 1 because the environment variable it needs at startup isn't set. Fix by defining env in the service file or unit override.
Quick answer
Add Environment=YOUR_VAR=value or EnvironmentFile=/path/to/file inside the [Service] block of the unit file, then run sudo systemctl daemon-reload && sudo systemctl restart your-service.
Why this happens
When you run a systemd service, it starts in a clean environment — no shell profile, no .bashrc, no .profile. The service's ExecStart process inherits only what systemd explicitly passes. If your app expects something like DATABASE_URL, API_KEY, or HOME to be set, and it isn't, the process exits with code 1. You'll see this in systemctl status your-service or journalctl -u your-service — the logs show a crash or a clear error like “undefined variable” or “missing configuration”. I've seen this most often with Node.js apps, Python scripts, and Docker containers where the app reads environment variables for configuration.
Fix steps
- Identify the missing variable
Runsudo journalctl -u your-service -n 50 --no-pager. Look for error lines likeKeyError: 'DB_HOST'orCannot read property 'PORT' of undefined. That's your missing variable.sudo journalctl -u myapp -n 20If you don't see a clear error, check your app's documentation for required environment variables.
- Edit the service unit
Usesudo systemctl edit your-serviceto create an override snippet (don't touch the original unit file directly — it gets overwritten on package updates). This opens a blank.conffile. Paste this:[Service]
Environment=YOUR_VAR=the_valueIf you have multiple variables, list them like this:
[Service]
Environment=DB_HOST=localhost
Environment=DB_PORT=5432
Environment=API_KEY=abc123Alternatively, use an
EnvironmentFileto keep secrets out of the unit file — just list variables in a separate file, one per line, e.g./etc/myapp.env. Then:[Service]
EnvironmentFile=/etc/myapp.env - Reload and restart
sudo systemctl daemon-reload
sudo systemctl restart your-service - Verify it's fixed
sudo systemctl status your-serviceYou should see
active (running)and no exit code 1.
Alternative fixes if step 2 doesn't work
- Check if the variable is actually read from a config file — some apps load env vars from
.envfiles, but systemd's working directory isn't your home directory. SetWorkingDirectory=/path/to/appin the[Service]section. - Use a wrapper script — if the app needs complex variable setup, write a shell script that sources a file and then runs the binary. Point
ExecStartat that script instead. This is hacky but works when you can't control the unit file. - Check for typos — I've spent 30 minutes debugging a missing variable only to find I typed
ENVIROMENTinstead ofEnvironment. Systemd won't warn you — it just ignores the typo.
Prevention tip
Always test your service with sudo systemd-run --unit=test --service-type=simple /path/to/your/app to see if it crashes in a clean environment. That simulates what systemd gives you. Also, avoid relying on shell profile variables in any service — put them in an EnvironmentFile from day one. If you're using Ansible or Puppet to deploy services, include the environment file creation as a separate task so you never forget it.
“The environment is not your shell. Treat it like a new container every time.” — that's how I think about systemd services now. It saves you hours.
For a full list of variables your app needs, run strings /path/to/binary | grep -E '^[A-Z_]+=' if it's a compiled binary, or check the app's README. No guesswork.
Was this solution helpful?