diff --git a/keyserver/src/responders/message-responders.js b/keyserver/src/responders/message-responders.js
--- a/keyserver/src/responders/message-responders.js
+++ b/keyserver/src/responders/message-responders.js
@@ -27,11 +27,13 @@
 } from 'lib/utils/validation-utils';
 
 import createMessages from '../creators/message-creator';
+import { SQL } from '../database/database';
 import {
   fetchMessageInfos,
   fetchMessageInfoForLocalID,
   fetchMessageInfoByID,
 } from '../fetchers/message-fetchers';
+import { fetchServerThreadInfos } from '../fetchers/thread-fetchers';
 import { checkThreadPermission } from '../fetchers/thread-permission-fetchers';
 import {
   fetchMedia,
@@ -213,11 +215,21 @@
     throw new ServerError('invalid_parameters');
   }
 
-  const [hasPermission, targetMessageUserInfos] = await Promise.all([
+  const [
+    serverThreadInfos,
+    hasPermission,
+    targetMessageUserInfos,
+  ] = await Promise.all([
+    fetchServerThreadInfos(SQL`t.id = ${threadID}`),
     checkThreadPermission(viewer, threadID, threadPermissions.VOICED),
     fetchKnownUserInfos(viewer, [targetMessageInfo.creatorID]),
   ]);
 
+  const targetMessageThreadInfo = serverThreadInfos.threadInfos[threadID];
+  if (targetMessageThreadInfo.sourceMessageID === targetMessageID) {
+    throw new ServerError('invalid_parameters');
+  }
+
   const targetMessageCreator =
     targetMessageUserInfos[targetMessageInfo.creatorID];
 
diff --git a/native/chat/reaction-message-utils.js b/native/chat/reaction-message-utils.js
--- a/native/chat/reaction-message-utils.js
+++ b/native/chat/reaction-message-utils.js
@@ -102,7 +102,10 @@
         ?.relationshipStatus,
   );
 
-  if (!targetMessageInfo.id) {
+  if (
+    !targetMessageInfo.id ||
+    threadInfo.sourceMessageID === targetMessageInfo.id
+  ) {
     return false;
   }