diff --git a/smartmontools/ChangeLog b/smartmontools/ChangeLog
index cd35d1f00808f6c8eef1a0b4178ef3c3dcaa7cd9..12a0b94f189ffdd908ec8bb506ec8fe496cb240d 100644
--- a/smartmontools/ChangeLog
+++ b/smartmontools/ChangeLog
@@ -2,6 +2,11 @@ $Id$
 
 2022-08-06  Christian Franke  <franke@computer.org>
 
+	Detect accidental use of smartd_warning script in '-M exec'.
+	smartd.cpp: Set SMARTD_SUBJECT to empty.
+	smartd_warning.sh.in, os_win32/smartd_warning.cmd: Abort if
+	SMARTD_SUBJECT is already nonempty.
+
 	smartd.cpp, popen_as_ugid.cpp: Don't use 'getdtablesize()'.
 	This function is declared 'legacy' since SUS 1997 and no longer part
 	of POSIX since 2004.  Use 'sysconf(_SC_OPEN_MAX)' instead.
diff --git a/smartmontools/os_win32/smartd_warning.cmd b/smartmontools/os_win32/smartd_warning.cmd
index 91d2694a5cdc528506abf54931f83a7a571930e4..a5a980f9e16db26a35fd14bec8f0261d2681d50a 100644
--- a/smartmontools/os_win32/smartd_warning.cmd
+++ b/smartmontools/os_win32/smartd_warning.cmd
@@ -4,7 +4,7 @@
 ::
 :: Home page of code is: http://www.smartmontools.org
 ::
-:: Copyright (C) 2012-17 Christian Franke
+:: Copyright (C) 2012-22 Christian Franke
 ::
 :: SPDX-License-Identifier: GPL-2.0-or-later
 ::
@@ -20,6 +20,12 @@ set err=
 cd /d %~dp0
 if errorlevel 1 goto ERROR
 
+:: Detect accidental use of '-M exec /path/to/smartd_warning.cmd'
+if not "!SMARTD_SUBJECT!" == "" (
+  echo smartd_warning.cmd: SMARTD_SUBJECT is already set - possible recursion
+  goto ERROR
+)
+
 :: Parse options
 set dryrun=
 if "%1" == "--dryrun" (
diff --git a/smartmontools/smartd.cpp b/smartmontools/smartd.cpp
index b0150c43158651004b25ebc85e92efafa9e86e6b..1bacd9c4c90c0c46a64050f04417bcd0920154c8 100644
--- a/smartmontools/smartd.cpp
+++ b/smartmontools/smartd.cpp
@@ -1110,7 +1110,7 @@ static void MailWarning(const dev_config & cfg, dev_state & state, int which, co
 
   // Export information in environment variables that will be useful
   // for user scripts
-  static env_buffer env[12];
+  static env_buffer env[13];
   env[0].set("SMARTD_MAILER", executable);
   env[1].set("SMARTD_MESSAGE", message);
   char dates[DATEANDEPOCHLEN];
@@ -1136,6 +1136,8 @@ static void MailWarning(const dev_config & cfg, dev_state & state, int which, co
     case 3: snprintf(dates, sizeof(dates), "%d", (0x01)<<mail->logged);
   }
   env[11].set("SMARTD_NEXTDAYS", dates);
+  // Avoid false positive recursion detection by smartd_warning.{sh,cmd}
+  env[12].set("SMARTD_SUBJECT", "");
 
   // now construct a command to send this as EMAIL
   if (!*executable)
diff --git a/smartmontools/smartd_warning.sh.in b/smartmontools/smartd_warning.sh.in
index a07e6b461168d62130e1095ea11b75a8ca78b001..1e06d55789fc6a9811938ba229b529f2d9f0e8f3 100644
--- a/smartmontools/smartd_warning.sh.in
+++ b/smartmontools/smartd_warning.sh.in
@@ -4,7 +4,7 @@
 #
 # Home page of code is: https://www.smartmontools.org
 #
-# Copyright (C) 2012-21 Christian Franke
+# Copyright (C) 2012-22 Christian Franke
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 #
@@ -27,6 +27,12 @@ os_mailer="@os_mailer@"
 # Plugin directory (disabled if empty)
 plugindir="@smartdplugindir@"
 
+# Detect accidental use of '-M exec /path/to/smartd_warning.sh'.
+if [ -n "$SMARTD_SUBJECT" ]; then
+  echo "$0: SMARTD_SUBJECT is already set - possible recursion" >&2
+  exit 1
+fi
+
 # Parse options
 dryrun=
 case $1 in