diff --git a/lib/actions/tunnelbroker-actions.js b/lib/actions/tunnelbroker-actions.js
--- a/lib/actions/tunnelbroker-actions.js
+++ b/lib/actions/tunnelbroker-actions.js
@@ -6,4 +6,7 @@
   failed: 'SET_TB_DEVICE_TOKEN_FAILED',
 });
 
+export const invalidateTunnelbrokerDeviceToken =
+  'INVALIDATE_TUNNELBROKER_DEVICE_TOKEN';
+
 export { setTBDeviceTokenActionTypes };
diff --git a/lib/reducers/tunnelbroker-device-token-reducer.js b/lib/reducers/tunnelbroker-device-token-reducer.js
--- a/lib/reducers/tunnelbroker-device-token-reducer.js
+++ b/lib/reducers/tunnelbroker-device-token-reducer.js
@@ -4,7 +4,10 @@
   setDeviceTokenActionTypes,
   type SetDeviceTokenStartedPayload,
 } from '../actions/device-actions.js';
-import { setTBDeviceTokenActionTypes } from '../actions/tunnelbroker-actions.js';
+import {
+  invalidateTunnelbrokerDeviceToken,
+  setTBDeviceTokenActionTypes,
+} from '../actions/tunnelbroker-actions.js';
 import type { BaseAction } from '../types/redux-types.js';
 import type { TunnelbrokerDeviceToken } from '../types/tunnelbroker-device-token-types.js';
 
@@ -24,6 +27,16 @@
   } else if (action.type === setTBDeviceTokenActionTypes.success) {
     const { deviceToken } = action.payload;
     return { ...state, tunnelbrokerToken: deviceToken };
+  } else if (action.type === invalidateTunnelbrokerDeviceToken) {
+    const { deviceToken } = action.payload;
+    if (state.localToken !== deviceToken) {
+      return state;
+    }
+    return {
+      ...state,
+      localToken: null,
+      tunnelbrokerToken: null,
+    };
   }
 
   return state;
diff --git a/lib/tunnelbroker/use-peer-to-peer-message-handler.js b/lib/tunnelbroker/use-peer-to-peer-message-handler.js
--- a/lib/tunnelbroker/use-peer-to-peer-message-handler.js
+++ b/lib/tunnelbroker/use-peer-to-peer-message-handler.js
@@ -4,6 +4,7 @@
 import _isEqual from 'lodash/fp/isEqual.js';
 import * as React from 'react';
 
+import { invalidateTunnelbrokerDeviceToken } from '../actions/tunnelbroker-actions.js';
 import { logOutActionTypes, useLogOut } from '../actions/user-actions.js';
 import {
   useBroadcastDeviceListUpdates,
@@ -36,7 +37,7 @@
 import { hasHigherDeviceID, olmSessionErrors } from '../utils/olm-utils.js';
 import { getClientMessageIDFromTunnelbrokerMessageID } from '../utils/peer-to-peer-communication-utils.js';
 import { useDispatchActionPromise } from '../utils/redux-promise-utils.js';
-import { useSelector } from '../utils/redux-utils.js';
+import { useDispatch, useSelector } from '../utils/redux-utils.js';
 
 // When logout is requested by primary device, logging out of Identity Service
 // is already handled by the primary device
@@ -123,6 +124,8 @@
   const broadcastDeviceListUpdates = useBroadcastDeviceListUpdates();
   const getAndUpdateDeviceListsForUsers = useGetAndUpdateDeviceListsForUsers();
 
+  const dispatch = useDispatch();
+
   const handleOlmMessageToDevice = useHandleOlmMessageToDevice();
 
   return React.useCallback(
@@ -312,10 +315,18 @@
             }`,
           );
         }
+      } else if (message.type === peerToPeerMessageTypes.BAD_DEVICE_TOKEN) {
+        dispatch({
+          type: invalidateTunnelbrokerDeviceToken,
+          payload: {
+            deviceToken: message.invalidatedToken,
+          },
+        });
       }
     },
     [
       broadcastDeviceListUpdates,
+      dispatch,
       foreignPeerDevices,
       getAndUpdateDeviceListsForUsers,
       getAuthMetadata,
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
@@ -1571,7 +1571,13 @@
         +type: 'PROCESS_DM_OPS',
         +payload: ProcessDMOpsPayload,
       }
-    | { +type: 'SCHEDULE_P2P_MESSAGES', +payload: ScheduleP2PMessagesPayload },
+    | { +type: 'SCHEDULE_P2P_MESSAGES', +payload: ScheduleP2PMessagesPayload }
+    | {
+        +type: 'INVALIDATE_TUNNELBROKER_DEVICE_TOKEN',
+        +payload: {
+          +deviceToken: string,
+        },
+      },
 }>;
 
 export type ActionPayload = ?(Object | Array<*> | $ReadOnlyArray<*> | string);