diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js
--- a/lib/reducers/message-reducer.js
+++ b/lib/reducers/message-reducer.js
@@ -983,6 +983,37 @@
         currentAsOf: messageStore.currentAsOf,
       },
     };
+  } else if (action.type === sendReactionMessageActionTypes.failed) {
+    const { localID, threadID } = action.payload;
+    const messageStoreOperations = [];
+
+    messageStoreOperations.push({
+      type: 'remove',
+      payload: { ids: [localID] },
+    });
+
+    const newMessageIDs = messageStore.threads[threadID].messageIDs.filter(
+      id => id !== localID,
+    );
+
+    const processedMessageStore = processMessageStoreOperations(
+      messageStore,
+      messageStoreOperations,
+    );
+
+    return {
+      messageStoreOperations,
+      messageStore: {
+        ...processedMessageStore,
+        threads: {
+          ...messageStore.threads,
+          [threadID]: {
+            ...messageStore.threads[threadID],
+            messageIDs: newMessageIDs,
+          },
+        },
+      },
+    };
   } else if (
     action.type === sendTextMessageActionTypes.success ||
     action.type === sendMultimediaMessageActionTypes.success ||
diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js
--- a/lib/types/redux-types.js
+++ b/lib/types/redux-types.js
@@ -538,9 +538,11 @@
       +type: 'SEND_REACTION_MESSAGE_FAILED',
       +error: true,
       +payload: Error & {
-        +targetMessageID: string,
+        +localID: string,
         +threadID: string,
+        +targetMessageID: string,
         +reaction: string,
+        +action: string,
       },
       +loadingInfo: LoadingInfo,
     }
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
@@ -10,6 +10,7 @@
 import { messageTypes } from 'lib/types/message-types';
 import type { RawReactionMessageInfo } from 'lib/types/messages/reaction';
 import type { BindServerCall, DispatchFunctions } from 'lib/utils/action-utils';
+import { cloneError } from 'lib/utils/errors';
 
 import type { InputState } from '../input/input-state';
 import type { AppNavigationProp } from '../navigation/app-navigator.react';
@@ -91,7 +92,11 @@
           cancelable: true,
         },
       );
-      throw e;
+
+      const copy = cloneError(e);
+      copy.localID = localID;
+      copy.threadID = threadID;
+      throw copy;
     }
   })();
 
diff --git a/web/chat/reaction-message-utils.js b/web/chat/reaction-message-utils.js
--- a/web/chat/reaction-message-utils.js
+++ b/web/chat/reaction-message-utils.js
@@ -14,6 +14,7 @@
   useDispatchActionPromise,
   useServerCall,
 } from 'lib/utils/action-utils';
+import { cloneError } from 'lib/utils/errors';
 
 import Alert from '../modals/alert.react';
 import { useSelector } from '../redux/redux-utils';
@@ -66,7 +67,11 @@
               Please try again later
             </Alert>,
           );
-          throw e;
+
+          const copy = cloneError(e);
+          copy.localID = localID;
+          copy.threadID = threadID;
+          throw copy;
         }
       })();