diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java
index ae8d23810..6edcd60f3 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java
@@ -134,6 +134,10 @@ public class SessionPlayerEntity extends PlayerEntity {
         return maxHealth;
     }
 
+    public float getHealth() {
+        return this.health;
+    }
+
     public void setHealth(float health) {
         this.health = health;
     }
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java
index d989fe964..67047d00e 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaSetHealthTranslator.java
@@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.protocol.java.entity.player;
 
 import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.player.ClientboundSetHealthPacket;
 import com.nukkitx.protocol.bedrock.data.AttributeData;
+import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
 import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
 import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
 import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
@@ -43,6 +44,18 @@ public class JavaSetHealthTranslator extends PacketTranslator<ClientboundSetHeal
     public void translate(GeyserSession session, ClientboundSetHealthPacket packet) {
         SessionPlayerEntity entity = session.getPlayerEntity();
 
+        float oldHealth = entity.getHealth();
+        if (oldHealth <= 0f && Math.ceil(packet.getHealth()) > 0f) {
+            // Needed as of 1.18.30 (tested with a totem of undying on SPIGOT 1.12.2
+            // This shouldn't be triggered on a proper respawn because JavaSetHealthTranslator sets the health back to 20
+            // https://github.com/GeyserMC/Geyser/issues/2957
+            RespawnPacket respawnPacket = new RespawnPacket();
+            respawnPacket.setRuntimeEntityId(0);
+            respawnPacket.setPosition(entity.getPosition());
+            respawnPacket.setState(RespawnPacket.State.SERVER_READY);
+            session.sendUpstreamPacket(respawnPacket);
+        }
+
         entity.setHealth(packet.getHealth());
 
         UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();