--- a/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SkullBlockEntity.java
@@ -114,13 +114,28 @@
         updateGameprofile(this.owner, (owner) -> {
             this.owner = owner;
             this.setChanged();
+            // Paper start
+        }, () -> {
+            final @Nullable Level level = this.getLevel();
+            return "SkullBlockEntity at " + this.getBlockPos() + (level == null ? "" : (" in level: " + level.dimension().location()));
+            // Paper end
         });
     }
 
     public static void updateGameprofile(@Nullable GameProfile owner, Consumer<GameProfile> callback) {
+        // Paper start
+        updateGameprofile(owner, callback, null);
+    }
+
+    private static final boolean DEBUG_INVALID_SKULL_PROFILES = Boolean.getBoolean("Paper.debugInvalidSkullProfiles");
+
+    public static void updateGameprofile(@Nullable GameProfile owner, Consumer<GameProfile> callback, final @Nullable java.util.function.Supplier<String> debugInfo) {
         if (owner != null && !StringUtil.isNullOrEmpty(owner.getName()) && (!owner.isComplete() || !owner.getProperties().containsKey("textures")) && profileCache != null && sessionService != null) {
+            final @Nullable Throwable trace = DEBUG_INVALID_SKULL_PROFILES ? new Throwable("updateGameprofile caller debug trace") : null;
             profileCache.getAsync(owner.getName(), (profile) -> {
-                Util.backgroundExecutor().execute(() -> {
+                Util.PROFILE_EXECUTOR.execute(() -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
+                    try {
+                    // Paper end
                     Util.ifElse(profile, (profilex) -> {
                         Property property = Iterables.getFirst(profilex.getProperties().get("textures"), (Property)null);
                         if (property == null) {
@@ -137,6 +152,20 @@
                             callback.accept(owner);
                         });
                     });
+                    // Paper start
+                    } catch (final Exception ex) {
+                        if (trace != null) {
+                            ex.addSuppressed(trace);
+                        }
+                        final String ownerMessage = "Original profile: '" + owner + "'";
+                        final String debugMessage = " Run with -DPaper.debugInvalidSkullProfiles=true for further debug information.";
+                        final String message = ownerMessage + (trace == null ? debugMessage : "");
+                        if (debugInfo == null) {
+                            throw new RuntimeException(message, ex);
+                        }
+                        throw new RuntimeException(debugInfo.get() + " " + message, ex);
+                    }
+                    // Paper end
                 });
             });
         } else {
