diff --git a/man/sd_notify.xml b/man/sd_notify.xml
index 52685c404b..fd229535d9 100644
--- a/man/sd_notify.xml
+++ b/man/sd_notify.xml
@@ -209,6 +209,11 @@
to allow the service manager to track the service's internal state, and present it to the user.
+ Starting with version 259, transitioning to the STOPPING state is final and cannot be undone
+ with another notification. If after sending STOPPING=1 the service doesn't
+ terminate within the stop timeout, all remaining processes in the unit will be killed.
+
+
diff --git a/src/core/service.c b/src/core/service.c
index 1918147525..535c833e25 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -5448,11 +5448,12 @@ static void service_notify_message_process_state(Service *s, char * const *tags)
return;
}
- /* Disallow resurrecting a dying service */
- if (s->notify_state == NOTIFY_STOPPING)
- return;
-
if (strv_contains(tags, "READY=1")) {
+ if (s->notify_state == NOTIFY_STOPPING) {
+ log_unit_error(UNIT(s),
+ "Service must stop after STOPPING=1 notification, refusing attempted transition to READY.");
+ return;
+ }
if (s->type == SERVICE_NOTIFY_RELOAD && s->state == SERVICE_START) {
r = service_check_reload_signal_handler(s, ", refusing service startup", ", ignoring");
@@ -5498,6 +5499,11 @@ static void service_notify_message_process_state(Service *s, char * const *tags)
service_enter_reload_post(s);
} else if (strv_contains(tags, "RELOADING=1")) {
+ if (s->notify_state == NOTIFY_STOPPING) {
+ log_unit_error(UNIT(s),
+ "Service must stop after STOPPING=1 notification, refusing attempted transition to RELOADING.");
+ return;
+ }
s->notify_state = NOTIFY_RELOADING;