The systemd daemon reported "Protocol not available" when attempting to send a notification via sd_notify, indicating that the systemd supervisor process isn’t listening for these status updates from the service.

Here are the common reasons and how to fix them:

1. The Service File is Missing Type=notify

  • Diagnosis: Check your service’s .service file. The critical line that enables sd_notify is Type=notify. If it’s missing or set to another type (like simple, forking, oneshot, or dbus), systemd will not set up the necessary communication socket for sd_notify.
    • Command: systemctl cat your-service-name.service
    • Example Output (Missing Type=notify):
      [Unit]
      Description=My Awesome Service
      
      [Service]
      ExecStart=/usr/local/bin/my-awesome-service
      Restart=on-failure
      
      [Install]
      WantedBy=multi-user.target
      
  • Fix: Add Type=notify to the [Service] section of your .service file.
    • Example Fix:
      [Unit]
      Description=My Awesome Service
      
      [Service]
      Type=notify
      ExecStart=/usr/local/bin/my-awesome-service
      Restart=on-failure
      
      [Install]
      WantedBy=multi-user.target
      
    • Why it works: Type=notify tells systemd to expect status updates from the service process and specifically instructs it to create a special socket ($NOTIFY_SOCKET) that the service can write to. Without this, the socket isn’t created, and sd_notify fails.
    • Action: After editing, reload systemd and restart your service:
      sudo systemctl daemon-reload
      sudo systemctl restart your-service-name.service
      

2. The Service is Not Actually Sending Notifications

  • Diagnosis: Even if Type=notify is present, the service itself must be written to call sd_notify() or a similar notification function. If the service code never attempts to send a notification, systemd might still report this error, or the notification will simply be ignored.
    • Check: Review the source code or documentation of your-service-name. Look for calls to sd_notify(), sd_notifyf(), or SD_NOTIFY_USE_FD.
  • Fix: Implement the notification logic in your service. This typically involves including the systemd/sd-daemon.h header and calling sd_notify(0, "READY=1") after the service has fully initialized and is ready to serve requests.
    • Example C Snippet:
      #include <systemd/sd-daemon.h>
      
      // ... after service initialization ...
      if (sd_notify(0, "READY=1") == 0) {
          fprintf(stderr, "sd_notify failed, but continuing\n");
      }
      // ... rest of service logic ...
      
    • Why it works: This ensures that your application actively communicates its readiness or other status changes to systemd via the established notification socket.

3. NOTIFY_SOCKET Environment Variable Not Set

  • Diagnosis: When Type=notify is used, systemd sets the NOTIFY_SOCKET environment variable within the service’s execution context. If this variable is not present, the service cannot find the socket to send its notifications.
    • Command: systemctl status your-service-name.service and look for the "Environment:" section.
    • Example Output (Missing NOTIFY_SOCKET):
      ● your-service-name.service - My Awesome Service
         Loaded: loaded (/etc/systemd/system/your-service-name.service; enabled; vendor preset: enabled)
         Active: active (running) since Mon 2023-10-27 10:00:00 UTC; 5min ago
      ...
      Environment:
      ...
      
      (If NOTIFY_SOCKET is present, it will be listed here with a path like /run/systemd/notify).
  • Fix: This is usually automatically handled by systemd when Type=notify is correctly set. If it’s missing, it points back to an issue with Type=notify not being recognized by systemd or a problem with systemd itself. Ensure systemd is running and healthy.
    • Why it works: The NOTIFY_SOCKET variable is how sd_notify() (and other notification functions) discover the specific socket file descriptor provided by systemd for communication.

4. Systemd Version Too Old

  • Diagnosis: Older versions of systemd might have had bugs or lacked full support for the Type=notify mechanism. While rare on modern systems, it’s a possibility.
    • Command: systemctl --version
  • Fix: Upgrade systemd to a more recent stable version.
    • Why it works: Newer versions have improved stability and feature completeness for systemd’s service management capabilities.

5. Permissions Issues with /run/systemd/notify

  • Diagnosis: The systemd notification socket is typically located in /run/systemd/notify. If the service process or the user it runs as lacks the necessary permissions to access or write to this socket file (though sd_notify typically works via file descriptors inherited from systemd, not direct file access), it could fail. This is very uncommon as systemd usually manages permissions correctly.
    • Check: ls -l /run/systemd/notify (this file might not always be visible as it’s a socket).
  • Fix: Ensure the service is not running under an extremely restrictive user or with NoNewPrivileges=yes in conjunction with other restrictive settings that might interfere with inherited file descriptors.
    • Why it works: The service needs to be able to communicate through the file descriptor that systemd associates with the notification socket.

6. SELinux or AppArmor Interference

  • Diagnosis: Mandatory Access Control systems like SELinux or AppArmor can sometimes block the communication between a service and systemd, including the notification socket.
    • Check SELinux: sudo ausearch -m avc -ts recent and look for denials related to your service’s executable or /run/systemd/notify.
    • Check AppArmor: sudo dmesg | grep -i apparmor or check /var/log/audit/audit.log or /var/log/syslog.
  • Fix: Adjust SELinux or AppArmor policies to allow the service to communicate with systemd’s notification socket. This is highly specific to your policy configuration.
    • Example SELinux (temporary permissive mode for testing): sudo semanage permissive -a your_service_t (replace your_service_t with the correct SELinux type for your service).
    • Why it works: MAC systems enforce access controls. Allowing the specific communication path between the service and the systemd notification mechanism grants the necessary permissions.

After applying these fixes, the next error you might encounter if your service is still not behaving as expected could be a READY=1 timeout, indicating that while systemd is receiving notifications, your service isn’t sending the READY=1 signal in a timely manner.

Want structured learning?

Take the full Systemd course →