Fix lỗi 'Job for service.service failed because the control process exited with error code' trên Linux

intermediate🐧 Linux2026-03-17| Linux (Ubuntu 20.04/22.04, Debian, CentOS 7/8, RHEL, Fedora) với systemd

Error Message

Job for <service_name>.service failed because the control process exited with error code.
#linux#systemd#service#troubleshooting

Chuyện gì đang xảy ra

Bạn chạy systemctl start myapp.service và systemd trả về:

Job for myapp.service failed because the control process exited with error code.
See "systemctl status myapp.service" and "journalctl -xe" for details.

Thông báo đó về bản chất không có nhiều thông tin — nó chỉ là một thông báo chung có nghĩa là "tiến trình thoát với mã khác không." Nguyên nhân thực sự nằm ở tầng sâu hơn. Đây là cách tìm ra nó.

Bước 1: Lấy lỗi thực sự

Hai lệnh sau, hãy chạy cả hai:

systemctl status myapp.service
journalctl -u myapp.service -n 50 --no-pager

Lệnh đầu tiên hiển thị một đoạn log ngắn và mã thoát. Lệnh thứ hai xuất 50 dòng log gần nhất trực tiếp ra terminal. Nếu lỗi vừa xảy ra, journalctl -xe cũng hoạt động và bổ sung thêm ngữ cảnh cấp kernel xung quanh thời điểm xảy ra lỗi.

Tìm các dòng được đánh dấu FAILED, error, hoặc output thô của tiến trình — đó là nơi chứa thông báo lỗi thực sự.

Bước 2: Xác định nguyên nhân gốc rễ

Sáu nguyên nhân sau chiếm phần lớn các trường hợp. Kiểm tra theo thứ tự này:

Đường dẫn binary sai hoặc file thực thi bị thiếu

ExecStart= trỏ đến đường dẫn không tồn tại, hoặc file không có quyền thực thi.

# Kiểm tra file unit
systemctl cat myapp.service

# Xác minh binary tồn tại
which myapp
ls -la /usr/local/bin/myapp

Sửa đường dẫn trong file unit, hoặc cài đặt binary còn thiếu.

Permission denied

Khi một service chạy với tư cách người dùng không phải root (qua User=), người dùng đó cần quyền đọc/thực thi đối với binary, file cấu hình và thư mục làm việc. Thiếu bất kỳ quyền nào cũng gây ra crash ngay lập tức.

# Kiểm tra service chạy với người dùng nào
grep -E 'User=|Group=|WorkingDirectory=' /etc/systemd/system/myapp.service

# Kiểm tra quyền truy cập thủ công
sudo -u serviceuser /usr/local/bin/myapp --config /etc/myapp/config.yaml

Điều chỉnh quyền sở hữu hoặc phân quyền:

chown serviceuser:serviceuser /etc/myapp/config.yaml
chmod 750 /var/lib/myapp

Port đã được sử dụng

Việc bind vào một port đang bị chiếm sẽ thất bại ngay khi khởi động. Nguyên nhân thường gặp: một instance khác của cùng ứng dụng, hoặc tiến trình còn sót lại từ lần crash trước.

ss -tlnp | grep :8080
# hoặc
lsof -i :8080

Tắt tiến trình xung đột, hoặc cập nhật port trong cấu hình ứng dụng.

Thiếu biến môi trường hoặc cấu hình sai

Ứng dụng phụ thuộc vào EnvironmentFile= sẽ thoát ngay lập tức nếu file đó bị thiếu hoặc chứa giá trị không hợp lệ.

# Kiểm tra EnvironmentFile có tồn tại không
grep EnvironmentFile /etc/systemd/system/myapp.service
ls -la /etc/myapp/.env

Tạo hoặc sửa file env, sau đó xác minh binary thực sự khởi động được khi chạy thủ công với tư cách người dùng của service:

sudo -u serviceuser bash -c 'source /etc/myapp/.env && /usr/local/bin/myapp'

Người dùng hoặc nhóm không tồn tại

Systemd sẽ từ chối khởi động service nếu User= hoặc Group= trong file unit không tồn tại trên hệ thống. Trường hợp này xảy ra khá nhiều sau khi cài đặt mới.

id serviceuser

Tạo nếu chưa có:

useradd --system --no-create-home --shell /usr/sbin/nologin serviceuser

Thiếu thư viện chia sẻ

Một binary có thể tồn tại trên đĩa nhưng vẫn không thể khởi chạy nếu không tìm thấy thư viện .so cần thiết lúc runtime.

ldd /usr/local/bin/myapp

Bất kỳ thư viện nào hiển thị not found đều cần được cài đặt. Cài package còn thiếu, hoặc thêm đường dẫn thư viện vào LD_LIBRARY_PATH thông qua chỉ thị Environment= trong file unit.

Bước 3: Áp dụng bản sửa và reload

Đã chỉnh sửa file unit tại /etc/systemd/system/myapp.service? Luôn reload daemon trước — systemd lưu file unit vào bộ nhớ và sẽ không nhận thay đổi nếu không reload:

systemctl daemon-reload
systemctl restart myapp.service

Chỉ thay đổi file cấu hình, phân quyền, hoặc file env (không phải file unit)? Bỏ qua daemon-reload và restart trực tiếp:

systemctl restart myapp.service

Xác minh

Kiểm tra trạng thái:

systemctl status myapp.service

Active: active (running) nghĩa là đã thành công. Theo dõi log trực tiếp khoảng 30 giây để bắt các lỗi xuất hiện muộn:

journalctl -u myapp.service -f

Muốn service tự khởi động sau khi reboot? Kích hoạt nó:

systemctl enable myapp.service

Bảng tóm tắt lệnh debug nhanh

  • systemctl status myapp.service — vài dòng log gần nhất + mã thoát
  • journalctl -u myapp.service -n 100 — toàn bộ log gần đây của unit
  • journalctl -xe — ngữ cảnh toàn hệ thống xung quanh thời điểm lỗi
  • systemctl cat myapp.service — hiển thị file unit đang được sử dụng
  • systemd-analyze verify myapp.service — kiểm tra cú pháp file unit

Bài học rút ra

"Control process exited with error code" là cách systemd nói: tiến trình trả về mã khác không. Chỉ vậy thôi. Hãy đi thẳng đến journalctl -u servicename mỗi lần — log riêng của unit hữu ích hơn nhiều so với journalctl -xe cho loại lỗi này. Và nếu bạn đang viết service của riêng mình, hãy ghi log ra stderr hoặc stdout. Systemd bắt cả hai, nên thông báo lỗi của bạn sẽ hiển thị ngay lập tức trong journalctl.

Related Error Notes