--- a/net/minecraft/world/entity/NeutralMob.java
+++ b/net/minecraft/world/entity/NeutralMob.java
@@ -8,8 +8,12 @@
 import net.minecraft.world.entity.player.Player;
 import net.minecraft.world.level.GameRules;
 import net.minecraft.world.level.Level;
+// CraftBukkit start
+import org.bukkit.event.entity.EntityTargetEvent;
+// CraftBukkit end
 
 public interface NeutralMob {
+
     String TAG_ANGER_TIME = "AngerTime";
     String TAG_ANGRY_AT = "AngryAt";
 
@@ -29,55 +33,51 @@
         if (this.getPersistentAngerTarget() != null) {
             nbt.putUUID("AngryAt", this.getPersistentAngerTarget());
         }
+
     }
 
     default void readPersistentAngerSaveData(Level world, CompoundTag nbt) {
         this.setRemainingPersistentAngerTime(nbt.getInt("AngerTime"));
         if (world instanceof ServerLevel) {
             if (!nbt.hasUUID("AngryAt")) {
-                this.setPersistentAngerTarget(null);
+                this.setPersistentAngerTarget((UUID) null);
             } else {
-                UUID uUID = nbt.getUUID("AngryAt");
-                this.setPersistentAngerTarget(uUID);
-                Entity entity = ((ServerLevel)world).getEntity(uUID);
-                if (entity != null) {
-                    if (entity instanceof Mob mob) {
-                        this.setTarget(mob);
-                        this.setLastHurtByMob(mob);
-                    }
+                UUID uuid = nbt.getUUID("AngryAt");
 
-                    if (entity instanceof Player player) {
-                        this.setTarget(player);
-                        this.setLastHurtByPlayer(player);
-                    }
-                }
+                this.setPersistentAngerTarget(uuid);
+                // Paper - Prevent entity loading causing async lookups; Moved diff to separate method
+                // If this entity already survived its first tick, e.g. is loaded and ticked in sync, actively
+                // tick the initial persistent anger.
+                // If not, let the first tick on the baseTick call the method later down the line.
+                if (this instanceof Entity entity && !entity.firstTick) this.tickInitialPersistentAnger(world);
             }
         }
     }
 
     default void updatePersistentAnger(ServerLevel world, boolean angerPersistent) {
-        LivingEntity livingEntity = this.getTarget();
-        UUID uUID = this.getPersistentAngerTarget();
-        if ((livingEntity == null || livingEntity.isDeadOrDying()) && uUID != null && world.getEntity(uUID) instanceof Mob) {
+        LivingEntity entityliving = this.getTarget();
+        UUID uuid = this.getPersistentAngerTarget();
+
+        if ((entityliving == null || entityliving.isDeadOrDying()) && uuid != null && world.getEntity(uuid) instanceof Mob) {
             this.stopBeingAngry();
         } else {
-            if (livingEntity != null && !Objects.equals(uUID, livingEntity.getUUID())) {
-                this.setPersistentAngerTarget(livingEntity.getUUID());
+            if (entityliving != null && !Objects.equals(uuid, entityliving.getUUID())) {
+                this.setPersistentAngerTarget(entityliving.getUUID());
                 this.startPersistentAngerTimer();
             }
 
-            if (this.getRemainingPersistentAngerTime() > 0 && (livingEntity == null || livingEntity.getType() != EntityType.PLAYER || !angerPersistent)) {
+            if (this.getRemainingPersistentAngerTime() > 0 && (entityliving == null || entityliving.getType() != EntityType.PLAYER || !angerPersistent)) {
                 this.setRemainingPersistentAngerTime(this.getRemainingPersistentAngerTime() - 1);
                 if (this.getRemainingPersistentAngerTime() == 0) {
                     this.stopBeingAngry();
                 }
             }
+
         }
     }
 
     default boolean isAngryAt(LivingEntity entity) {
-        return this.canAttack(entity)
-            && (entity.getType() == EntityType.PLAYER && this.isAngryAtAllPlayers(entity.level()) || entity.getUUID().equals(this.getPersistentAngerTarget()));
+        return !this.canAttack(entity) ? false : (entity.getType() == EntityType.PLAYER && this.isAngryAtAllPlayers(entity.level()) ? true : entity.getUUID().equals(this.getPersistentAngerTarget()));
     }
 
     default boolean isAngryAtAllPlayers(Level world) {
@@ -102,9 +102,9 @@
     }
 
     default void stopBeingAngry() {
-        this.setLastHurtByMob(null);
-        this.setPersistentAngerTarget(null);
-        this.setTarget(null);
+        this.setLastHurtByMob((LivingEntity) null);
+        this.setPersistentAngerTarget((UUID) null);
+        this.setTarget((LivingEntity) null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FORGOT_TARGET, true); // CraftBukkit
         this.setRemainingPersistentAngerTime(0);
     }
 
@@ -117,8 +117,34 @@
 
     void setTarget(@Nullable LivingEntity target);
 
+    boolean setTarget(@Nullable LivingEntity entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason reason, boolean fireEvent); // CraftBukkit
+
     boolean canAttack(LivingEntity target);
 
     @Nullable
     LivingEntity getTarget();
+
+    // Paper start - Prevent entity loading causing async lookups
+    // Update last hurt when ticking
+    default void tickInitialPersistentAnger(Level level) {
+        UUID target = getPersistentAngerTarget();
+        if (target == null) {
+            return;
+        }
+
+        Entity entity = ((ServerLevel) level).getEntity(target);
+
+        if (entity != null) {
+            if (entity instanceof Mob mob) {
+                this.setTarget(mob, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
+                this.setLastHurtByMob(mob);
+            }
+
+            if (entity instanceof Player player) {
+                this.setTarget(player, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
+                this.setLastHurtByPlayer(player);
+            }
+        }
+    }
+    // Paper end - Prevent entity loading causing async lookups
 }
