--- a/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -79,39 +_,71 @@
 
     @Override
     protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
         if (level instanceof ServerLevel serverLevel) {
             BlockPos blockPos = pos.immutable();
             effectApplier.runBefore(InsideBlockEffectType.EXTINGUISH, entity1 -> {
-                if (entity1.isOnFire() && entity1.mayInteract(serverLevel, blockPos)) {
-                    this.handleEntityOnFireInside(state, level, blockPos);
+                if (entity1.isOnFire() && (entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity1.mayInteract(serverLevel, blockPos)) { // Paper - Fixes MC-248588
+                    // Paper start - cauldron level change event
+                    if (this.handleEntityOnFireInside(state, level, blockPos, entity1)) { // Paper - track entity
+                        InsideBlockEffectType.EXTINGUISH.effect().affect(entity1, blockPos); // apply extinguishing if event was not cancelled.
+                    }
+                    // Paper end - cauldron level change event
                 }
             });
         }
 
-        effectApplier.apply(InsideBlockEffectType.EXTINGUISH);
+        // effectApplier.apply(InsideBlockEffectType.EXTINGUISH); // Paper - manually applied above - cauldron level change event - delay to not extinguish when event is cancelled
     }
 
-    private void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) {
+    // CraftBukkit start
+    private boolean handleEntityOnFireInside(BlockState state, Level level, BlockPos pos, @javax.annotation.Nullable Entity entity) {
         if (this.precipitationType == Biome.Precipitation.SNOW) {
-            lowerFillLevel(Blocks.WATER_CAULDRON.defaultBlockState().setValue(LEVEL, state.getValue(LEVEL)), level, pos);
+            return lowerFillLevel(Blocks.WATER_CAULDRON.defaultBlockState().setValue(LEVEL, state.getValue(LEVEL)), level, pos, entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); // CraftBukkit
         } else {
-            lowerFillLevel(state, level, pos);
+            return lowerFillLevel(state, level, pos, entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); // CraftBukkit
         }
     }
 
     public static void lowerFillLevel(BlockState state, Level level, BlockPos pos) {
+    // Paper start
+        lowerFillLevel(state, level, pos, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.UNKNOWN);
+    }
+    public static boolean lowerFillLevel(BlockState state, Level level, BlockPos pos, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) {
+    // Paper end
         int i = state.getValue(LEVEL) - 1;
         BlockState blockState = i == 0 ? Blocks.CAULDRON.defaultBlockState() : state.setValue(LEVEL, i);
-        level.setBlockAndUpdate(pos, blockState);
-        level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
-    }
+        return changeLevel(level, pos, blockState, entity, reason); // Paper
+    }
+    // CraftBukkit start
+    // Paper start - Call CauldronLevelChangeEvent
+    public static boolean changeLevel(Level level, BlockPos pos, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable
+        return changeLevel(level, pos, newBlock, entity, reason, true);
+    }
+
+    public static boolean changeLevel(Level level, BlockPos pos, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable
+        // Paper end - Call CauldronLevelChangeEvent
+        org.bukkit.craftbukkit.block.CraftBlockState newState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(level, pos);
+        newState.setData(newBlock);
+
+        org.bukkit.event.block.CauldronLevelChangeEvent event = new org.bukkit.event.block.CauldronLevelChangeEvent(
+                org.bukkit.craftbukkit.block.CraftBlock.at(level, pos),
+                (entity == null) ? null : entity.getBukkitEntity(), reason, newState
+        );
+        if (!event.callEvent()) {
+            return false;
+        }
+        newState.place(3);
+        if (sendGameEvent) level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent
+        return true;
+    }
+    // CraftBukkit end
 
     @Override
     public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) {
         if (CauldronBlock.shouldHandlePrecipitation(level, precipitation) && state.getValue(LEVEL) != 3 && precipitation == this.precipitationType) {
             BlockState blockState = state.cycle(LEVEL);
-            level.setBlockAndUpdate(pos, blockState);
-            level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
+            changeLevel(level, pos, blockState, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit
         }
     }
 
@@ -129,8 +_,11 @@
     protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) {
         if (!this.isFull(state)) {
             BlockState blockState = state.setValue(LEVEL, state.getValue(LEVEL) + 1);
-            level.setBlockAndUpdate(pos, blockState);
-            level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
+            // CraftBukkit start
+            if (!changeLevel(level, pos, blockState, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) {
+                return;
+            }
+            // CraftBukkit end
             level.levelEvent(1047, pos, 0);
         }
     }
