diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java
index e908f8898b..2e9b303ea9 100644
--- a/Mage.Server/src/main/java/mage/server/Session.java
+++ b/Mage.Server/src/main/java/mage/server/Session.java
@@ -28,7 +28,6 @@
 package mage.server;
 
 import java.util.*;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -66,7 +65,6 @@ public class Session {
     private final Date timeConnected;
     private boolean isAdmin = false;
     private final AsynchInvokerCallbackHandler callbackHandler;
-    private boolean error = false;
 
     private final ReentrantLock lock;
 
@@ -348,42 +346,30 @@ public class Session {
         }
     }
 
+    public boolean setLock() {
+        return lock.tryLock();
+    }
+
+    public void unlock() {
+        lock.unlock();
+    }
+
     public void kill(DisconnectReason reason) {
-        boolean lockSet = false;
-        try {
-            if (lock.tryLock(5000, TimeUnit.MILLISECONDS)) {
-                lockSet = true;
-                logger.debug("SESSION LOCK SET sessionId: " + sessionId);
-            } else {
-                logger.error("SESSION LOCK - kill: userId " + userId);
-            }
-            UserManager.instance.removeUserFromAllTablesAndChat(userId, reason);
-        } catch (InterruptedException ex) {
-            logger.error("SESSION LOCK - kill: userId " + userId, ex);
-        } finally {
-            if (lockSet) {
-                lock.unlock();
-                logger.debug("SESSION LOCK UNLOCK sessionId: " + sessionId);
-
-            }
-        }
-
+        UserManager.instance.removeUserFromAllTablesAndChat(userId, reason);
     }
 
     public void fireCallback(final ClientCallback call) {
-        if (error) {
-            return;
-        }
         try {
-            call.setMessageId(messageId++);
-            callbackHandler.handleCallbackOneway(new Callback(call));
+            if (!isLocked()) { // only fire callback if session isn't about to be killed or in the process of handling disconnect detection
+                call.setMessageId(messageId++);
+                callbackHandler.handleCallbackOneway(new Callback(call));
+            }
         } catch (HandleCallbackException ex) {
-            error = true; // to reduce repeated SESSION CALLBACK EXCEPTION
             UserManager.instance.getUser(userId).ifPresent(user -> {
+                SessionManager.instance.disconnect(sessionId, LostConnection);
                 user.setUserState(User.UserState.Disconnected);
                 logger.warn("SESSION CALLBACK EXCEPTION - " + user.getName() + " userId " + userId + " - cause: " + getBasicCause(ex).toString());
                 logger.trace("Stack trace:", ex);
-                SessionManager.instance.disconnect(sessionId, LostConnection);
             });
         }
     }
diff --git a/Mage.Server/src/main/java/mage/server/SessionManager.java b/Mage.Server/src/main/java/mage/server/SessionManager.java
index b3d9c0db00..07b124f70d 100644
--- a/Mage.Server/src/main/java/mage/server/SessionManager.java
+++ b/Mage.Server/src/main/java/mage/server/SessionManager.java
@@ -125,6 +125,7 @@ public enum SessionManager {
     public void disconnect(String sessionId, DisconnectReason reason) {
         Session session = sessions.get(sessionId);
         if (session != null) {
+            boolean lockWasSet = session.setLock();
             if (!sessions.containsKey(sessionId)) {
                 // session was removed meanwhile by another thread so we can return
                 return;
@@ -148,7 +149,9 @@ public enum SessionManager {
                 default:
                     logger.trace("endSession: unexpected reason  " + reason.toString() + " - sessionId: " + sessionId);
             }
-
+            if (lockWasSet) {
+                session.unlock();
+            }
         }
 
     }