diff --git a/patches/api/Add-PlayerKickEvent-causes.patch b/patches/api/Add-PlayerKickEvent-causes.patch
index bfc9033594..4caed2691b 100644
--- a/patches/api/Add-PlayerKickEvent-causes.patch
+++ b/patches/api/Add-PlayerKickEvent-causes.patch
@@ -110,6 +110,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +        ILLEGAL_CHARACTERS,
 +
++        OUT_OF_ORDER_CHAT,
++
++        UNSIGNED_CHAT,
++
++        CHAT_VALIDATION_FAILED,
++
++        TOO_MANY_PENDING_CHATS,
++
 +        SELF_INTERACTION,
 +
 +        DUPLICATE_LOGIN,
diff --git a/patches/server/Add-PlayerKickEvent-causes.patch b/patches/server/Add-PlayerKickEvent-causes.patch
index 515a259e17..6731f86881 100644
--- a/patches/server/Add-PlayerKickEvent-causes.patch
+++ b/patches/server/Add-PlayerKickEvent-causes.patch
@@ -97,27 +97,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
          this.chatPreviewThrottler.tick();
 @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+         return this.server.isSingleplayerOwner(this.player.getGameProfile());
+     }
  
++    @io.papermc.paper.annotation.DoNotUse // Paper
      public void disconnect(String s) {
          // Paper start
 -        this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s));
 +        this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
-+    }
-+
-+    public void disconnect(String s, PlayerKickEvent.Cause cause) {
-+        this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s), cause);
      }
  
++    public void disconnect(String s, PlayerKickEvent.Cause cause) {
++        this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s), cause);
++    }
++
++    @io.papermc.paper.annotation.DoNotUse // Paper
      public void disconnect(final Component reason) {
 -        this.disconnect(PaperAdventure.asAdventure(reason));
 +        this.disconnect(PaperAdventure.asAdventure(reason), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
++    }
++
++    public void disconnect(final Component reason, PlayerKickEvent.Cause cause) {
++        this.disconnect(PaperAdventure.asAdventure(reason), cause);
      }
  
 -    public void disconnect(net.kyori.adventure.text.Component reason) {
-+    public void disconnect(final Component reason, PlayerKickEvent.Cause cause) {
-+        this.disconnect(PaperAdventure.asAdventure(reason), cause);
-+    }
-+
 +    public void disconnect(net.kyori.adventure.text.Component reason, org.bukkit.event.player.PlayerKickEvent.Cause cause) {
          // Paper end
          // CraftBukkit start - fire PlayerKickEvent
@@ -140,6 +144,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          } else {
              Entity entity = this.player.getRootVehicle();
  
+@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+         PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
+         if (packet.getId() == this.awaitingTeleport) {
+             if (this.awaitingPositionFromClient == null) {
+-                this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"));
++                this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause
+                 return;
+             }
+ 
 @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
          // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); // Paper - run this async
          // CraftBukkit start
@@ -196,7 +209,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
          if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(0.0D), packet.getY(0.0D), packet.getZ(0.0D), packet.getYRot(0.0F), packet.getXRot(0.0F))) {
 -            this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"));
-+            this.disconnect(Component.translatable(("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT)); // Paper - kick event cause
++            this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause
          } else {
              ServerLevel worldserver = this.player.getLevel();
  
@@ -236,6 +249,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          } else {
              if (this.tryHandleChat(packet.message(), packet.timeStamp(), packet.lastSeenMessages())) {
                  // this.server.submit(() -> { // CraftBukkit - async chat
+@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+     @Override
+     public void handleChatCommand(ServerboundChatCommandPacket packet) {
+         if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.command())) {
+-            this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"));
++            this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper
+         } else {
+             if (this.tryHandleChat(packet.command(), packet.timeStamp(), packet.lastSeenMessages())) {
+                 this.server.submit(() -> {
+@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+     private boolean tryHandleChat(String message, Instant timestamp, LastSeenMessages.Update acknowledgment) {
+         if (!this.updateChatOrder(timestamp)) {
+             ServerGamePacketListenerImpl.LOGGER.warn("{} sent out-of-order chat: '{}'", this.player.getName().getString(), message);
+-            this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"));
++            this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"), org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event cause
+             return false;
+         } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales
+             this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false));
+@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+         ChatSender chatsender = this.player.asChatSender();
+ 
+         if (chatsender.profilePublicKey() != null && !message.verify(chatsender)) {
+-            this.disconnect(Component.translatable("multiplayer.disconnect.unsigned_chat"));
++            this.disconnect(Component.translatable("multiplayer.disconnect.unsigned_chat"), org.bukkit.event.player.PlayerKickEvent.Cause.UNSIGNED_CHAT); // Paper - kick event cause
+             return false;
+         } else {
+             if (message.hasExpiredServer(Instant.now())) {
 @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
          // this.chatSpamTickCount += 20;
          if (this.chatSpamTickCount.addAndGet(20) > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
@@ -246,6 +286,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      }
 @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+ 
+     private void handleValidationFailure(Set<LastSeenMessagesValidator.ErrorCondition> reasons) {
+         ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message from {}, reasons: {}", this.player.getName().getString(), reasons.stream().map(LastSeenMessagesValidator.ErrorCondition::message).collect(Collectors.joining(",")));
+-        this.disconnect(Component.translatable("multiplayer.disconnect.chat_validation_failed"));
++        this.disconnect(Component.translatable("multiplayer.disconnect.chat_validation_failed"), org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event cause
+     }
+ 
+     @Override
+@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+             }
+ 
+             if (i > 4096) {
+-                this.disconnect(Component.translatable("multiplayer.disconnect.too_many_pending_chats"));
++                this.disconnect(Component.translatable("multiplayer.disconnect.too_many_pending_chats"), org.bukkit.event.player.PlayerKickEvent.Cause.TOO_MANY_PENDING_CHATS); // Paper - kick event cause
+             }
+ 
+         }
+@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
          // Spigot Start
          if ( entity == this.player && !this.player.isSpectator() )
          {
diff --git a/patches/server/Add-some-minimal-debug-information-to-chat-packet-er.patch b/patches/server/Add-some-minimal-debug-information-to-chat-packet-er.patch
index e03dddc5c1..a9c9fe2ef8 100644
--- a/patches/server/Add-some-minimal-debug-information-to-chat-packet-er.patch
+++ b/patches/server/Add-some-minimal-debug-information-to-chat-packet-er.patch
@@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -            ServerGamePacketListenerImpl.LOGGER.warn("{} sent out-of-order chat: '{}'", this.player.getName().getString(), message);
 +            ServerGamePacketListenerImpl.LOGGER.warn("{} sent out-of-order chat: '{}': {} > {}", this.player.getName().getString(), message, this.lastChatTimeStamp.get().getEpochSecond(), timestamp.getEpochSecond()); // Paper
              this.server.scheduleOnMain(() -> { // Paper - push to main
-             this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"));
+             this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"), org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event cause
              }); // Paper - push to main
 @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
              return false;
diff --git a/patches/server/Kick-on-main-for-illegal-chat.patch b/patches/server/Kick-on-main-for-illegal-chat.patch
index f4044618f7..a195ae0ffd 100644
--- a/patches/server/Kick-on-main-for-illegal-chat.patch
+++ b/patches/server/Kick-on-main-for-illegal-chat.patch
@@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      public void handleChatCommand(ServerboundChatCommandPacket packet) {
          if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.command())) {
 +            this.server.scheduleOnMain(() -> { // Paper - push to main for event firing
-             this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"));
+             this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper
 +            }); // Paper - push to main for event firing
          } else {
              if (this.tryHandleChat(packet.command(), packet.timeStamp(), packet.lastSeenMessages())) {
@@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          if (!this.updateChatOrder(timestamp)) {
              ServerGamePacketListenerImpl.LOGGER.warn("{} sent out-of-order chat: '{}'", this.player.getName().getString(), message);
 +            this.server.scheduleOnMain(() -> { // Paper - push to main
-             this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"));
+             this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"), org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event cause
 +            }); // Paper - push to main
              return false;
          } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales