--- a/net/minecraft/world/level/chunk/storage/IChunkLoader.java
+++ b/net/minecraft/world/level/chunk/storage/IChunkLoader.java
@@ -22,6 +22,15 @@
 import net.minecraft.world.level.levelgen.structure.PersistentStructureLegacy;
 import net.minecraft.world.level.storage.WorldPersistentData;
 
+// CraftBukkit start
+import java.util.concurrent.ExecutionException;
+import net.minecraft.server.level.ChunkProviderServer;
+import net.minecraft.server.level.WorldServer;
+import net.minecraft.world.level.GeneratorAccess;
+import net.minecraft.world.level.chunk.status.ChunkStatus;
+import net.minecraft.world.level.dimension.WorldDimension;
+// CraftBukkit end
+
 public class IChunkLoader implements AutoCloseable {
 
     public static final int LAST_MONOLYTH_STRUCTURE_DATA_VERSION = 1493;
@@ -39,13 +48,56 @@
         return this.worker.isOldChunkAround(chunkcoordintpair, i);
     }
 
-    public NBTTagCompound upgradeChunkTag(ResourceKey<World> resourcekey, Supplier<WorldPersistentData> supplier, NBTTagCompound nbttagcompound, Optional<ResourceKey<MapCodec<? extends ChunkGenerator>>> optional) {
+    // CraftBukkit start
+    private boolean check(ChunkProviderServer cps, int x, int z) {
+        ChunkCoordIntPair pos = new ChunkCoordIntPair(x, z);
+        if (cps != null) {
+            if (cps.hasChunk(x, z)) {
+                return true;
+            }
+        }
+
+        NBTTagCompound nbt;
+        try {
+            nbt = read(pos).get().orElse(null);
+        } catch (InterruptedException | ExecutionException ex) {
+            throw new RuntimeException(ex);
+        }
+        if (nbt != null) {
+            NBTTagCompound level = nbt.getCompound("Level");
+            if (level.getBoolean("TerrainPopulated")) {
+                return true;
+            }
+
+            ChunkStatus status = ChunkStatus.byName(level.getString("Status"));
+            if (status != null && status.isOrAfter(ChunkStatus.FEATURES)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public NBTTagCompound upgradeChunkTag(ResourceKey<WorldDimension> resourcekey, Supplier<WorldPersistentData> supplier, NBTTagCompound nbttagcompound, Optional<ResourceKey<MapCodec<? extends ChunkGenerator>>> optional, ChunkCoordIntPair pos, @Nullable GeneratorAccess generatoraccess) {
+        // CraftBukkit end
         int i = getVersion(nbttagcompound);
 
         if (i == SharedConstants.getCurrentVersion().getDataVersion().getVersion()) {
             return nbttagcompound;
         } else {
             try {
+                // CraftBukkit start
+                if (i < 1466) {
+                    NBTTagCompound level = nbttagcompound.getCompound("Level");
+                    if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) {
+                        ChunkProviderServer cps = (generatoraccess == null) ? null : ((WorldServer) generatoraccess).getChunkSource();
+                        if (check(cps, pos.x - 1, pos.z) && check(cps, pos.x - 1, pos.z - 1) && check(cps, pos.x, pos.z - 1)) {
+                            level.putBoolean("LightPopulated", true);
+                        }
+                    }
+                }
+                // CraftBukkit end
+
                 if (i < 1493) {
                     nbttagcompound = DataFixTypes.CHUNK.update(this.fixerUpper, nbttagcompound, i, 1493);
                     if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
@@ -70,7 +122,7 @@
         }
     }
 
-    private PersistentStructureLegacy getLegacyStructureHandler(ResourceKey<World> resourcekey, Supplier<WorldPersistentData> supplier) {
+    private PersistentStructureLegacy getLegacyStructureHandler(ResourceKey<WorldDimension> resourcekey, Supplier<WorldPersistentData> supplier) { // CraftBukkit
         PersistentStructureLegacy persistentstructurelegacy = this.legacyStructureHandler;
 
         if (persistentstructurelegacy == null) {
@@ -85,7 +137,7 @@
         return persistentstructurelegacy;
     }
 
-    public static void injectDatafixingContext(NBTTagCompound nbttagcompound, ResourceKey<World> resourcekey, Optional<ResourceKey<MapCodec<? extends ChunkGenerator>>> optional) {
+    public static void injectDatafixingContext(NBTTagCompound nbttagcompound, ResourceKey<WorldDimension> resourcekey, Optional<ResourceKey<MapCodec<? extends ChunkGenerator>>> optional) { // CraftBukkit
         NBTTagCompound nbttagcompound1 = new NBTTagCompound();
 
         nbttagcompound1.putString("dimension", resourcekey.location().toString());
