--- a/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SkullBlockEntity.java
@@ -3,6 +3,7 @@
 import com.mojang.authlib.GameProfile;
 import com.mojang.authlib.minecraft.MinecraftSessionService;
 import com.mojang.authlib.yggdrasil.ProfileResult;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
@@ -21,6 +22,7 @@
 import net.minecraft.world.level.block.state.BlockState;
 
 public class SkullBlockEntity extends BlockEntity {
+
     public static final String TAG_SKULL_OWNER = "SkullOwner";
     public static final String TAG_NOTE_BLOCK_SOUND = "note_block_sound";
     @Nullable
@@ -30,7 +32,8 @@
     @Nullable
     private static Executor mainThreadExecutor;
     private static final Executor CHECKED_MAIN_THREAD_EXECUTOR = (runnable) -> {
-        Executor executor = mainThreadExecutor;
+        Executor executor = SkullBlockEntity.mainThreadExecutor;
+
         if (executor != null) {
             executor.execute(runnable);
         }
@@ -48,24 +51,25 @@
     }
 
     public static void setup(Services apiServices, Executor executor) {
-        profileCache = apiServices.profileCache();
-        sessionService = apiServices.sessionService();
-        mainThreadExecutor = executor;
+        SkullBlockEntity.profileCache = apiServices.profileCache();
+        SkullBlockEntity.sessionService = apiServices.sessionService();
+        SkullBlockEntity.mainThreadExecutor = executor;
     }
 
     public static void clear() {
-        profileCache = null;
-        sessionService = null;
-        mainThreadExecutor = null;
+        SkullBlockEntity.profileCache = null;
+        SkullBlockEntity.sessionService = null;
+        SkullBlockEntity.mainThreadExecutor = null;
     }
 
     @Override
     protected void saveAdditional(CompoundTag nbt) {
         super.saveAdditional(nbt);
         if (this.owner != null) {
-            CompoundTag compoundTag = new CompoundTag();
-            NbtUtils.writeGameProfile(compoundTag, this.owner);
-            nbt.put("SkullOwner", compoundTag);
+            CompoundTag nbttagcompound1 = new CompoundTag();
+
+            NbtUtils.writeGameProfile(nbttagcompound1, this.owner);
+            nbt.put("SkullOwner", nbttagcompound1);
         }
 
         if (this.noteBlockSound != null) {
@@ -80,9 +84,10 @@
         if (nbt.contains("SkullOwner", 10)) {
             this.setOwner(NbtUtils.readGameProfile(nbt.getCompound("SkullOwner")));
         } else if (nbt.contains("ExtraType", 8)) {
-            String string = nbt.getString("ExtraType");
-            if (!StringUtil.isNullOrEmpty(string)) {
-                this.setOwner(new GameProfile(Util.NIL_UUID, string));
+            String s = nbt.getString("ExtraType");
+
+            if (!StringUtil.isNullOrEmpty(s)) {
+                this.setOwner(new GameProfile(Util.NIL_UUID, s));
             }
         }
 
@@ -93,7 +98,7 @@
     }
 
     public static void animation(Level world, BlockPos pos, BlockState state, SkullBlockEntity blockEntity) {
-        if (state.hasProperty(SkullBlock.POWERED) && state.getValue(SkullBlock.POWERED)) {
+        if (state.hasProperty(SkullBlock.POWERED) && (Boolean) state.getValue(SkullBlock.POWERED)) {
             blockEntity.isAnimating = true;
             ++blockEntity.animationTickCount;
         } else {
@@ -103,7 +108,7 @@
     }
 
     public float getAnimation(float tickDelta) {
-        return this.isAnimating ? (float)this.animationTickCount + tickDelta : (float)this.animationTickCount;
+        return this.isAnimating ? (float) this.animationTickCount + tickDelta : (float) this.animationTickCount;
     }
 
     @Nullable
@@ -127,7 +132,7 @@
     }
 
     public void setOwner(@Nullable GameProfile owner) {
-        synchronized(this) {
+        synchronized (this) {
             this.owner = owner;
         }
 
@@ -135,11 +140,11 @@
     }
 
     private void updateOwnerProfile() {
-        if (this.owner != null && !Util.isBlank(this.owner.getName()) && !hasTextures(this.owner)) {
-            fetchGameProfile(this.owner.getName()).thenAcceptAsync((profile) -> {
-                this.owner = profile.orElse(this.owner);
+        if (this.owner != null && !Util.isBlank(this.owner.getName()) && !SkullBlockEntity.hasTextures(this.owner)) {
+            SkullBlockEntity.fetchGameProfile(this.owner.getName()).thenAcceptAsync((optional) -> {
+                this.owner = (GameProfile) optional.orElse(this.owner);
                 this.setChanged();
-            }, CHECKED_MAIN_THREAD_EXECUTOR);
+            }, SkullBlockEntity.CHECKED_MAIN_THREAD_EXECUTOR);
         } else {
             this.setChanged();
         }
@@ -151,10 +156,11 @@
             return NbtUtils.readGameProfile(nbt.getCompound("SkullOwner"));
         } else {
             if (nbt.contains("SkullOwner", 8)) {
-                String string = nbt.getString("SkullOwner");
-                if (!Util.isBlank(string)) {
+                String s = nbt.getString("SkullOwner");
+
+                if (!Util.isBlank(s)) {
                     nbt.remove("SkullOwner");
-                    resolveGameProfile(nbt, string);
+                    SkullBlockEntity.resolveGameProfile(nbt, s);
                 }
             }
 
@@ -163,44 +169,60 @@
     }
 
     public static void resolveGameProfile(CompoundTag nbt) {
-        String string = nbt.getString("SkullOwner");
-        if (!Util.isBlank(string)) {
-            resolveGameProfile(nbt, string);
+        String s = nbt.getString("SkullOwner");
+
+        if (!Util.isBlank(s)) {
+            SkullBlockEntity.resolveGameProfile(nbt, s);
+            // CraftBukkit start
+        } else {
+            net.minecraft.nbt.ListTag textures = nbt.getCompound("SkullOwner").getCompound("Properties").getList("textures", 10); // Safe due to method contracts
+            for (int i = 0; i < textures.size(); i++) {
+                if (textures.get(i) instanceof CompoundTag && !((CompoundTag) textures.get(i)).contains("Signature", 8) && ((CompoundTag) textures.get(i)).getString("Value").trim().isEmpty()) {
+                    nbt.remove("SkullOwner");
+                    break;
+                }
+            }
+            // CraftBukkit end
         }
 
     }
 
     private static void resolveGameProfile(CompoundTag nbt, String name) {
-        fetchGameProfile(name).thenAccept((profile) -> {
-            nbt.put("SkullOwner", NbtUtils.writeGameProfile(new CompoundTag(), profile.orElse(new GameProfile(Util.NIL_UUID, name))));
+        SkullBlockEntity.fetchGameProfile(name).thenAccept((optional) -> {
+            nbt.put("SkullOwner", NbtUtils.writeGameProfile(new CompoundTag(), (GameProfile) optional.orElse(new GameProfile(Util.NIL_UUID, name))));
         });
     }
 
     private static CompletableFuture<Optional<GameProfile>> fetchGameProfile(String name) {
-        GameProfileCache gameProfileCache = profileCache;
-        return gameProfileCache == null ? CompletableFuture.completedFuture(Optional.empty()) : gameProfileCache.getAsync(name).thenCompose((profile) -> {
-            return profile.isPresent() ? fillProfileTextures(profile.get()) : CompletableFuture.completedFuture(Optional.empty());
-        }).thenApplyAsync((profile) -> {
-            GameProfileCache gameProfileCache = profileCache;
-            if (gameProfileCache != null) {
-                profile.ifPresent(gameProfileCache::add);
-                return profile;
+        GameProfileCache usercache = SkullBlockEntity.profileCache;
+
+        return usercache == null ? CompletableFuture.completedFuture(Optional.empty()) : usercache.getAsync(name).thenCompose((optional) -> {
+            return optional.isPresent() ? SkullBlockEntity.fillProfileTextures((GameProfile) optional.get()) : CompletableFuture.completedFuture(Optional.empty());
+        }).thenApplyAsync((optional) -> {
+            GameProfileCache usercache1 = SkullBlockEntity.profileCache;
+
+            if (usercache1 != null) {
+                Objects.requireNonNull(usercache1);
+                optional.ifPresent(usercache1::add);
+                return optional;
             } else {
                 return Optional.empty();
             }
-        }, CHECKED_MAIN_THREAD_EXECUTOR);
+        }, SkullBlockEntity.CHECKED_MAIN_THREAD_EXECUTOR);
     }
 
     public static CompletableFuture<Optional<GameProfile>> fillProfileTextures(GameProfile profile) {
-        return hasTextures(profile) ? CompletableFuture.completedFuture(Optional.of(profile)) : CompletableFuture.supplyAsync(() -> {
-            MinecraftSessionService minecraftSessionService = sessionService;
-            if (minecraftSessionService != null) {
-                ProfileResult profileResult = minecraftSessionService.fetchProfile(profile.getId(), true);
-                return profileResult == null ? Optional.of(profile) : Optional.of(profileResult.profile());
+        return SkullBlockEntity.hasTextures(profile) ? CompletableFuture.completedFuture(Optional.of(profile)) : CompletableFuture.supplyAsync(() -> {
+            MinecraftSessionService minecraftsessionservice = SkullBlockEntity.sessionService;
+
+            if (minecraftsessionservice != null) {
+                ProfileResult profileresult = minecraftsessionservice instanceof com.destroystokyo.paper.profile.PaperMinecraftSessionService paperMinecraftSessionService ? paperMinecraftSessionService.fetchProfile(profile, true) : minecraftsessionservice.fetchProfile(profile.getId(), true); // Paper
+
+                return profileresult == null ? Optional.of(profile) : Optional.of(profileresult.profile());
             } else {
                 return Optional.empty();
             }
-        }, Util.backgroundExecutor());
+        }, Util.PROFILE_EXECUTOR); // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
     }
 
     private static boolean hasTextures(GameProfile profile) {
