diff --git a/lib/handlers/peer-to-peer-message-handler.js b/lib/handlers/peer-to-peer-message-handler.js
--- a/lib/handlers/peer-to-peer-message-handler.js
+++ b/lib/handlers/peer-to-peer-message-handler.js
@@ -15,6 +15,7 @@
 async function peerToPeerMessageHandler(
   message: PeerToPeerMessage,
   identityClient: IdentityServiceClient,
+  messageID: string,
 ): Promise<void> {
   const { olmAPI } = getConfig();
   if (message.type === peerToPeerMessageTypes.OUTBOUND_SESSION_CREATION) {
@@ -91,19 +92,32 @@
   } else if (message.type === peerToPeerMessageTypes.ENCRYPTED_MESSAGE) {
     try {
       await olmAPI.initializeCryptoAccount();
-      const decrypted = await olmAPI.decrypt(
+      const decrypted = await olmAPI.decryptSequential(
         message.encryptedData,
         message.senderInfo.deviceID,
+        messageID,
       );
       console.log(
         'Decrypted message from device ' +
           `${message.senderInfo.deviceID}: ${decrypted}`,
       );
     } catch (e) {
-      console.log(
-        'Error decrypting message from device ' +
-          `${message.senderInfo.deviceID}: ${e.message}`,
-      );
+      if (e.message?.includes(olmSessionErrors.messageAlreadyDecrypted)) {
+        console.log(
+          'Received already decrypted message from device ' +
+            `${message.senderInfo.deviceID}.`,
+        );
+      } else if (e.message?.includes(olmSessionErrors.messageOutOfOrder)) {
+        console.log(
+          'Received out-of-order message from device ' +
+            `${message.senderInfo.deviceID}.`,
+        );
+      } else {
+        console.log(
+          'Error decrypting message from device ' +
+            `${message.senderInfo.deviceID}: ${e.message}`,
+        );
+      }
     }
   } else if (message.type === peerToPeerMessageTypes.REFRESH_KEY_REQUEST) {
     try {
diff --git a/lib/tunnelbroker/tunnelbroker-context.js b/lib/tunnelbroker/tunnelbroker-context.js
--- a/lib/tunnelbroker/tunnelbroker-context.js
+++ b/lib/tunnelbroker/tunnelbroker-context.js
@@ -277,7 +277,11 @@
               return;
             }
             const peerToPeerMessage: PeerToPeerMessage = rawPeerToPeerMessage;
-            void peerToPeerMessageHandler(peerToPeerMessage, identityClient);
+            void peerToPeerMessageHandler(
+              peerToPeerMessage,
+              identityClient,
+              message.messageID,
+            );
           } else if (
             message.type ===
             tunnelbrokerMessageTypes.MESSAGE_TO_DEVICE_REQUEST_STATUS
diff --git a/lib/utils/olm-utils.js b/lib/utils/olm-utils.js
--- a/lib/utils/olm-utils.js
+++ b/lib/utils/olm-utils.js
@@ -123,6 +123,12 @@
   // The client received a session request with a lower session version,
   // this request can be ignored.
   alreadyCreated: 'OLM_SESSION_ALREADY_CREATED',
+  // If using sequential decrypt this error means that message was decrypted.
+  // Otherwise, it could mean that the receiver chain advance beyond and the key
+  // to decrypt that message was discarded.
+  messageAlreadyDecrypted: 'OLM_ALREADY_DECRYPTED_OR_KEYS_SKIPPED',
+  // One or more messages were skipped.
+  messageOutOfOrder: 'OLM_MESSAGE_OUT_OF_ORDER',
 });
 
 function hasHigherDeviceID(