--- a/net/minecraft/world/entity/animal/Bucketable.java
+++ b/net/minecraft/world/entity/animal/Bucketable.java
@@ -88,9 +_,19 @@
     static <T extends LivingEntity & Bucketable> Optional<InteractionResult> bucketMobPickup(Player player, InteractionHand hand, T entity) {
         ItemStack itemInHand = player.getItemInHand(hand);
         if (itemInHand.getItem() == Items.WATER_BUCKET && entity.isAlive()) {
-            entity.playSound(entity.getPickupSound(), 1.0F, 1.0F);
+            // CraftBukkit start
+            // entity.playSound(entity.getPickupSound(), 1.0F, 1.0F); // CraftBukkit - moved down
             ItemStack bucketItemStack = entity.getBucketItemStack();
             entity.saveToBucketTag(bucketItemStack);
+            org.bukkit.event.player.PlayerBucketEntityEvent playerBucketFishEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerFishBucketEvent(entity, player, itemInHand, bucketItemStack, hand);
+            bucketItemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(playerBucketFishEvent.getEntityBucket());
+            if (playerBucketFishEvent.isCancelled()) {
+                player.containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket
+                entity.resendPossiblyDesyncedEntityData((ServerPlayer) player); // Paper
+                return Optional.of(InteractionResult.FAIL);
+            }
+            entity.playSound(entity.getPickupSound(), 1.0F, 1.0F);
+            // CraftBukkit end
             ItemStack itemStack = ItemUtils.createFilledResult(itemInHand, player, bucketItemStack, false);
             player.setItemInHand(hand, itemStack);
             Level level = entity.level();
@@ -98,7 +_,7 @@
                 CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer)player, bucketItemStack);
             }
 
-            entity.discard();
+            entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
             return Optional.of(InteractionResult.SUCCESS);
         } else {
             return Optional.empty();
