diff --git a/man/sd_notify.xml b/man/sd_notify.xml
index 5e6c9d6dbc..0c993e31f7 100644
--- a/man/sd_notify.xml
+++ b/man/sd_notify.xml
@@ -499,6 +499,26 @@
successfully. Specifically, no error is returned when a file descriptor is attempted to be stored using
FDSTORE=1 but the service is not actually configured to permit storing of file
descriptors (see above).
+
+
+ Errors
+
+ Returned errors may indicate the following problems:
+
+
+
+ -E2BIG
+
+ More file descriptors passed at once than the system allows. On Linux the number of
+ file descriptors that may be passed across AF_UNIX sockets at once is 253, see
+ unix7 for
+ details.
+
+
+
+
+
diff --git a/src/basic/missing_socket.h b/src/basic/missing_socket.h
index 55de40a321..8460ce13bf 100644
--- a/src/basic/missing_socket.h
+++ b/src/basic/missing_socket.h
@@ -68,3 +68,10 @@
#ifndef IPV6_RECVFRAGSIZE
#define IPV6_RECVFRAGSIZE 77
#endif
+
+/* The maximum number of fds that SCM_RIGHTS accepts. This is an internal kernel constant, but very much
+ * useful for userspace too. It's documented in unix(7) these days, hence should be fairly reliable to define
+ * here. */
+#ifndef SCM_MAX_FD
+#define SCM_MAX_FD 253U
+#endif
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index faf45c2750..4d3d678cb4 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -472,6 +472,12 @@ static int pid_notify_with_fds_internal(
assert_return(state, -EINVAL);
assert_return(fds || n_fds == 0, -EINVAL);
+ /* Let's make sure the multiplications below don't overflow, and also return a recognizable error in
+ * case the caller tries to send more fds than the kernel limit. The kernel would return EINVAL which
+ * is not too useful I'd say. */
+ if (n_fds > SCM_MAX_FD)
+ return -E2BIG;
+
const char *e = getenv("NOTIFY_SOCKET");
if (!e)
return 0;
diff --git a/src/notify/notify.c b/src/notify/notify.c
index 8937457ec9..6afb9560c6 100644
--- a/src/notify/notify.c
+++ b/src/notify/notify.c
@@ -453,6 +453,8 @@ static int run(int argc, char* argv[]) {
r = sd_pid_notify_with_fds(arg_pid.pid, /* unset_environment= */ false, msg, a, k);
}
+ if (r == -E2BIG)
+ return log_error_errno(r, "Too many file descriptors passed.");
if (r < 0)
return log_error_errno(r, "Failed to notify init system: %m");
if (r == 0)