diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java b/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java
index 56776cb12..5e9d67ad7 100644
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java
+++ b/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java
@@ -89,6 +89,15 @@ public final class LootTableEvents {
 		}
 	});
 
+	/**
+	 * This event can be used for post-processing after all loot tables have been loaded and modified by Fabric.
+	 */
+	public static final Event<Loaded> ALL_LOADED = EventFactory.createArrayBacked(Loaded.class, listeners -> (resourceManager, lootManager) -> {
+		for (Loaded listener : listeners) {
+			listener.onLootTablesLoaded(resourceManager, lootManager);
+		}
+	});
+
 	public interface Replace {
 		/**
 		 * Replaces loot tables.
@@ -116,4 +125,14 @@ public final class LootTableEvents {
 		 */
 		void modifyLootTable(ResourceManager resourceManager, LootManager lootManager, Identifier id, LootTable.Builder tableBuilder, LootTableSource source);
 	}
+
+	public interface Loaded {
+		/**
+		 * Called when all loot tables have been loaded and {@link LootTableEvents#REPLACE} and {@link LootTableEvents#MODIFY} have been invoked.
+		 *
+		 * @param resourceManager the server resource manager
+		 * @param lootManager     the loot manager
+		 */
+		void onLootTablesLoaded(ResourceManager resourceManager, LootManager lootManager);
+	}
 }
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootManagerMixin.java b/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootManagerMixin.java
index aa684722b..9c8625f77 100644
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootManagerMixin.java
+++ b/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootManagerMixin.java
@@ -95,5 +95,6 @@ abstract class LootManagerMixin {
 		});
 
 		this.keyToValue = newTables.build();
+		LootTableEvents.ALL_LOADED.invoker().onLootTablesLoaded(resourceManager, lootManager);
 	}
 }
diff --git a/fabric-loot-api-v2/src/testmod/java/net/fabricmc/fabric/test/loot/LootTest.java b/fabric-loot-api-v2/src/testmod/java/net/fabricmc/fabric/test/loot/LootTest.java
index 4a7236347..1f34b42dd 100644
--- a/fabric-loot-api-v2/src/testmod/java/net/fabricmc/fabric/test/loot/LootTest.java
+++ b/fabric-loot-api-v2/src/testmod/java/net/fabricmc/fabric/test/loot/LootTest.java
@@ -92,5 +92,13 @@ public class LootTest implements ModInitializer {
 				tableBuilder.modifyPools(poolBuilder -> poolBuilder.with(ItemEntry.builder(Items.EMERALD)));
 			}
 		});
+
+		LootTableEvents.ALL_LOADED.register((resourceManager, lootManager) -> {
+			LootTable blackWoolTable = lootManager.getLootTable(Blocks.BLACK_WOOL.getLootTableId());
+
+			if (blackWoolTable == LootTable.EMPTY) {
+				throw new AssertionError("black wool loot table should not be empty");
+			}
+		});
 	}
 }