diff --git a/patches/server/Configurable-Entity-Despawn-Time.patch b/patches/server/Configurable-Entity-Despawn-Time.patch
new file mode 100644
index 0000000000..94a820598d
--- /dev/null
+++ b/patches/server/Configurable-Entity-Despawn-Time.patch
@@ -0,0 +1,39 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Kevin Raneri <kevin.raneri@gmail.com>
+Date: Mon, 30 Sep 2024 09:50:55 -0700
+Subject: [PATCH] Configurable Entity Despawn Time
+
+
+diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/entity/Entity.java
++++ b/src/main/java/net/minecraft/world/entity/Entity.java
+@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+     private UUID originWorld;
+     public boolean freezeLocked = false; // Paper - Freeze Tick Lock API
+     public boolean fixedPose = false; // Paper - Expand Pose API
++    private final int despawnTime; // Paper - entity despawn time limit
+ 
+     public void setOrigin(@javax.annotation.Nonnull Location location) {
+         this.origin = location.toVector();
+@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ 
+     public Entity(EntityType<?> type, Level world) {
+         this.id = Entity.ENTITY_COUNTER.incrementAndGet();
++        this.despawnTime = type == EntityType.PLAYER ? -1 : world.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit
+         this.passengers = ImmutableList.of();
+         this.deltaMovement = Vec3.ZERO;
+         this.bb = Entity.INITIAL_AABB;
+@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+     }
+ 
+     public void tick() {
++        // Paper start - entity despawn time limit
++        if (this.despawnTime >= 0 && this.tickCount >= this.despawnTime) {
++            this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN);
++            return;
++        }
++        // Paper end - entity despawn time limit
+         this.baseTick();
+     }
+ 
diff --git a/patches/server/Paper-config-files.patch b/patches/server/Paper-config-files.patch
index 1427153f6b..f3927904c4 100644
--- a/patches/server/Paper-config-files.patch
+++ b/patches/server/Paper-config-files.patch
@@ -132,23 +132,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import io.leangen.geantyref.TypeToken;
 +import io.papermc.paper.configuration.constraint.Constraint;
 +import io.papermc.paper.configuration.constraint.Constraints;
-+import net.minecraft.core.RegistryAccess;
-+import net.minecraft.resources.ResourceLocation;
-+import net.minecraft.server.level.ServerLevel;
-+import net.minecraft.world.level.GameRules;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.jetbrains.annotations.MustBeInvokedByOverriders;
-+import org.slf4j.Logger;
-+import org.spongepowered.configurate.CommentedConfigurationNode;
-+import org.spongepowered.configurate.ConfigurateException;
-+import org.spongepowered.configurate.ConfigurationNode;
-+import org.spongepowered.configurate.ConfigurationOptions;
-+import org.spongepowered.configurate.NodePath;
-+import org.spongepowered.configurate.objectmapping.ObjectMapper;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+import org.spongepowered.configurate.util.CheckedFunction;
-+import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
-+
 +import java.io.IOException;
 +import java.lang.reflect.Type;
 +import java.nio.file.AccessDeniedException;
@@ -159,6 +142,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.util.NoSuchElementException;
 +import java.util.Objects;
 +import java.util.function.UnaryOperator;
++import net.minecraft.core.RegistryAccess;
++import net.minecraft.resources.ResourceLocation;
++import net.minecraft.server.level.ServerLevel;
++import net.minecraft.world.level.GameRules;
++import org.jetbrains.annotations.MustBeInvokedByOverriders;
++import org.jspecify.annotations.Nullable;
++import org.slf4j.Logger;
++import org.spongepowered.configurate.CommentedConfigurationNode;
++import org.spongepowered.configurate.ConfigurateException;
++import org.spongepowered.configurate.ConfigurationNode;
++import org.spongepowered.configurate.ConfigurationOptions;
++import org.spongepowered.configurate.objectmapping.ObjectMapper;
++import org.spongepowered.configurate.serialize.SerializationException;
++import org.spongepowered.configurate.util.CheckedFunction;
++import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
 +
 +public abstract class Configurations<G, W> {
 +
@@ -501,7 +499,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import net.kyori.adventure.text.format.NamedTextColor;
 +import net.minecraft.network.protocol.Packet;
 +import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.slf4j.Logger;
 +import org.spongepowered.configurate.objectmapping.ConfigSerializable;
 +import org.spongepowered.configurate.objectmapping.meta.Comment;
@@ -829,15 +827,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.configuration;
 +
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.spongepowered.configurate.objectmapping.meta.NodeResolver;
-+
 +import java.lang.annotation.Documented;
 +import java.lang.annotation.ElementType;
 +import java.lang.annotation.Retention;
 +import java.lang.annotation.RetentionPolicy;
 +import java.lang.annotation.Target;
 +import java.lang.reflect.AnnotatedElement;
++import org.jspecify.annotations.Nullable;
++import org.spongepowered.configurate.objectmapping.meta.NodeResolver;
 +
 +@Documented
 +@Retention(RetentionPolicy.RUNTIME)
@@ -903,6 +900,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
 +import it.unimi.dsi.fastutil.objects.Reference2LongMap;
 +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap;
++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
++import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
 +import java.io.File;
 +import java.io.IOException;
 +import java.lang.reflect.Type;
@@ -925,8 +924,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.apache.commons.lang3.RandomStringUtils;
 +import org.bukkit.configuration.ConfigurationSection;
 +import org.bukkit.configuration.file.YamlConfiguration;
-+import org.checkerframework.checker.nullness.qual.Nullable;
 +import org.jetbrains.annotations.VisibleForTesting;
++import org.jspecify.annotations.Nullable;
 +import org.slf4j.Logger;
 +import org.spigotmc.SpigotConfig;
 +import org.spigotmc.SpigotWorldConfig;
@@ -1108,6 +1107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                .serializers(serializers -> serializers
 +                    .register(new TypeToken<Reference2IntMap<?>>() {}, new FastutilMapSerializer.SomethingToPrimitive<Reference2IntMap<?>>(Reference2IntOpenHashMap::new, Integer.TYPE))
 +                    .register(new TypeToken<Reference2LongMap<?>>() {}, new FastutilMapSerializer.SomethingToPrimitive<Reference2LongMap<?>>(Reference2LongOpenHashMap::new, Long.TYPE))
++                    .register(new TypeToken<Reference2ObjectMap<?, ?>>() {}, new FastutilMapSerializer.SomethingToSomething<Reference2ObjectMap<?, ?>>(Reference2ObjectOpenHashMap::new))
 +                    .register(new TypeToken<Table<?, ?, ?>>() {}, new TableSerializer())
 +                    .register(DespawnRange.class, DespawnRange.SERIALIZER)
 +                    .register(StringRepresentableSerializer::isValidFor, new StringRepresentableSerializer())
@@ -1436,6 +1436,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import io.papermc.paper.configuration.legacy.RequiresSpigotInitialization;
 +import io.papermc.paper.configuration.mapping.MergeMap;
 +import io.papermc.paper.configuration.serializer.NbtPathSerializer;
++import io.papermc.paper.configuration.serializer.collections.MapSerializer;
 +import io.papermc.paper.configuration.transformation.world.FeatureSeedsGeneration;
 +import io.papermc.paper.configuration.type.BooleanOrDefault;
 +import io.papermc.paper.configuration.type.DespawnRange;
@@ -1451,6 +1452,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
 +import it.unimi.dsi.fastutil.objects.Reference2LongMap;
 +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap;
++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
++import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
 +import java.util.Arrays;
 +import java.util.IdentityHashMap;
 +import java.util.List;
@@ -1628,6 +1631,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                }
 +            }
 +
++            @MapSerializer.ThrowExceptions
++            public Reference2ObjectMap<EntityType<?>, IntOr.Disabled> despawnTime = Util.make(new Reference2ObjectOpenHashMap<>(), map -> {
++                map.put(EntityType.SNOWBALL, IntOr.Disabled.DISABLED);
++                map.put(EntityType.LLAMA_SPIT, IntOr.Disabled.DISABLED);
++            });
++
 +            @PostProcess
 +            public void precomputeDespawnDistances() throws SerializationException {
 +                for (Map.Entry<MobCategory, DespawnRangePair> entry : this.despawnRanges.entrySet()) {
@@ -2058,7 +2067,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.lang.annotation.RetentionPolicy;
 +import java.lang.annotation.Target;
 +import java.lang.reflect.Type;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.spongepowered.configurate.objectmapping.meta.Constraint;
 +import org.spongepowered.configurate.serialize.SerializationException;
 +
@@ -2101,7 +2110,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.configuration.legacy;
 +
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.spigotmc.SpigotWorldConfig;
 +import org.spongepowered.configurate.ConfigurationNode;
 +import org.spongepowered.configurate.objectmapping.meta.NodeResolver;
@@ -2138,10 +2147,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import com.google.common.collect.HashBasedTable;
 +import com.google.common.collect.Table;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.spigotmc.SpigotWorldConfig;
-+import org.spongepowered.configurate.objectmapping.meta.NodeResolver;
-+
 +import java.lang.annotation.Documented;
 +import java.lang.annotation.ElementType;
 +import java.lang.annotation.Retention;
@@ -2149,8 +2154,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.lang.annotation.Target;
 +import java.lang.reflect.AnnotatedElement;
 +import java.lang.reflect.Constructor;
-+import java.util.Map;
-+import java.util.concurrent.ConcurrentHashMap;
++import org.jspecify.annotations.Nullable;
++import org.spigotmc.SpigotWorldConfig;
++import org.spongepowered.configurate.objectmapping.meta.NodeResolver;
 +
 +@Documented
 +@Retention(RetentionPolicy.RUNTIME)
@@ -2227,14 +2233,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +package io.papermc.paper.configuration.mapping;
 +
 +import io.papermc.paper.configuration.ConfigurationPart;
-+import io.papermc.paper.configuration.Configurations;
-+import io.papermc.paper.configuration.PaperConfigurations;
 +import io.papermc.paper.configuration.WorldConfiguration;
 +import java.lang.reflect.AnnotatedType;
 +import java.lang.reflect.Field;
 +import java.util.Collections;
 +import java.util.Map;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.spongepowered.configurate.objectmapping.FieldDiscoverer;
 +import org.spongepowered.configurate.serialize.SerializationException;
 +
@@ -2291,7 +2295,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.util.Iterator;
 +import java.util.Map;
 +import java.util.Objects;
-+import org.checkerframework.checker.nullness.qual.Nullable;
 +import org.spongepowered.configurate.objectmapping.FieldDiscoverer;
 +import org.spongepowered.configurate.serialize.SerializationException;
 +
@@ -2323,7 +2326,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                Map.Entry<Field, Object> entry = iter.next();
 +                if (entry.getKey().isAnnotationPresent(MergeMap.class) && Map.class.isAssignableFrom(entry.getKey().getType()) && intermediate.get(entry.getKey()) instanceof Map<?, ?> map) {
 +                    iter.remove();
-+                    @Nullable Map<Object, Object> existingMap = (Map<Object, Object>) entry.getKey().get(instance);
++                    Map<Object, Object> existingMap = (Map<Object, Object>) entry.getKey().get(instance);
 +                    if (existingMap != null) {
 +                        existingMap.putAll(map);
 +                    } else {
@@ -2364,7 +2367,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.util.HashMap;
 +import java.util.Map;
 +import java.util.function.Supplier;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.spongepowered.configurate.serialize.SerializationException;
 +import org.spongepowered.configurate.util.CheckedFunction;
 +import org.spongepowered.configurate.util.CheckedSupplier;
@@ -2400,7 +2403,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                final Constructor<?> constructor;
 +                final CheckedSupplier<Object, ReflectiveOperationException> instanceSupplier;
 +                if (type.getEnclosingClass() != null && !Modifier.isStatic(type.getModifiers())) {
-+                    final @Nullable Object instance = this.instanceMap.get(type.getEnclosingClass());
++                    final Object instance = this.instanceMap.get(type.getEnclosingClass());
 +                    if (instance == null) {
 +                        throw new SerializationException("Cannot create a new instance of an inner class " + type.getName() + " without an instance of its enclosing class " + type.getEnclosingClass().getName());
 +                    }
@@ -2453,18 +2456,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +@Retention(RetentionPolicy.RUNTIME)
 +public @interface MergeMap {
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/mapping/package-info.java b/src/main/java/io/papermc/paper/configuration/mapping/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/mapping/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.mapping;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/package-info.java b/src/main/java/io/papermc/paper/configuration/package-info.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
 --- /dev/null
 +++ b/src/main/java/io/papermc/paper/configuration/package-info.java
 @@ -0,0 +0,0 @@
-+@DefaultQualifier(NonNull.class)
++@NullMarked
 +package io.papermc.paper.configuration;
 +
-+import org.checkerframework.checker.nullness.qual.NonNull;
-+import org.checkerframework.framework.qual.DefaultQualifier;
-\ No newline at end of file
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -2546,16 +2557,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import com.mojang.logging.LogUtils;
 +import io.leangen.geantyref.TypeToken;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.slf4j.Logger;
-+import org.spongepowered.configurate.serialize.ScalarSerializer;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+import org.spongepowered.configurate.util.EnumLookup;
-+
 +import java.lang.reflect.Type;
 +import java.util.Arrays;
 +import java.util.List;
 +import java.util.function.Predicate;
++import org.jspecify.annotations.Nullable;
++import org.slf4j.Logger;
++import org.spongepowered.configurate.serialize.ScalarSerializer;
++import org.spongepowered.configurate.serialize.SerializationException;
++import org.spongepowered.configurate.util.EnumLookup;
 +
 +import static io.leangen.geantyref.GenericTypeReflector.erase;
 +
@@ -2575,14 +2585,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    public @Nullable Enum<?> deserialize(final Type type, final Object obj) throws SerializationException {
 +        final String enumConstant = obj.toString();
 +        final Class<? extends Enum> typeClass = erase(type).asSubclass(Enum.class);
-+        @Nullable Enum<?> ret = EnumLookup.lookupEnum(typeClass, enumConstant);
++        Enum<?> ret = EnumLookup.lookupEnum(typeClass, enumConstant);
 +        if (ret == null) {
 +            ret = EnumLookup.lookupEnum(typeClass, enumConstant.replace("-", "_"));
 +        }
 +        if (ret == null) {
 +            boolean longer = typeClass.getEnumConstants().length > 10;
 +            List<String> options = Arrays.stream(typeClass.getEnumConstants()).limit(10L).map(Enum::name).toList();
-+            LOGGER.error("Invalid enum constant provided, expected one of [" + String.join(", " ,options) + (longer ? ", ..." : "") + "], but got " + enumConstant);
++            LOGGER.error("Invalid enum constant provided, expected one of [{}{}], but got {}", String.join(", ", options), longer ? ", ..." : "", enumConstant);
 +        }
 +        return ret;
 +    }
@@ -2664,16 +2674,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import io.leangen.geantyref.TypeToken;
 +import io.papermc.paper.configuration.serializer.collections.MapSerializer;
 +import io.papermc.paper.util.ObfHelper;
-+import net.minecraft.network.protocol.Packet;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.slf4j.Logger;
-+import org.spongepowered.configurate.serialize.ScalarSerializer;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+
 +import java.lang.reflect.Type;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.function.Predicate;
++import net.minecraft.network.protocol.Packet;
++import org.jspecify.annotations.Nullable;
++import org.slf4j.Logger;
++import org.spongepowered.configurate.serialize.ScalarSerializer;
++import org.spongepowered.configurate.serialize.SerializationException;
 +
 +@SuppressWarnings("Convert2Diamond")
 +public final class PacketClassSerializer extends ScalarSerializer<Class<? extends Packet<?>>> implements MapSerializer.WriteBack {
@@ -2703,14 +2712,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    @SuppressWarnings("unchecked")
 +    @Override
 +    public Class<? extends Packet<?>> deserialize(final Type type, final Object obj) throws SerializationException {
-+        @Nullable Class<?> packetClass = null;
++        Class<?> packetClass = null;
 +        for (final String subpackage : SUBPACKAGES) {
 +            final String fullClassName = "net.minecraft.network.protocol." + subpackage + "." + obj;
 +            try {
 +                packetClass = Class.forName(fullClassName);
 +                break;
 +            } catch (final ClassNotFoundException ex) {
-+                final @Nullable String spigotClassName = MOJANG_TO_OBF.get(fullClassName);
++                final String spigotClassName = MOJANG_TO_OBF.get(fullClassName);
 +                if (spigotClassName != null) {
 +                    try {
 +                        packetClass = Class.forName(spigotClassName);
@@ -2750,17 +2759,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.configuration.serializer;
 +
-+import net.minecraft.util.StringRepresentable;
-+import net.minecraft.world.entity.MobCategory;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.spongepowered.configurate.serialize.ScalarSerializer;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+
 +import java.lang.reflect.Type;
 +import java.util.Collections;
 +import java.util.Map;
 +import java.util.function.Function;
 +import java.util.function.Predicate;
++import net.minecraft.util.StringRepresentable;
++import net.minecraft.world.entity.MobCategory;
++import org.jspecify.annotations.Nullable;
++import org.spongepowered.configurate.serialize.ScalarSerializer;
++import org.spongepowered.configurate.serialize.SerializationException;
 +
 +public final class StringRepresentableSerializer extends ScalarSerializer<StringRepresentable> {
 +    private static final Map<Type, Function<String, StringRepresentable>> TYPES = Collections.synchronizedMap(Map.ofEntries(
@@ -2810,44 +2818,53 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import io.leangen.geantyref.GenericTypeReflector;
 +import io.leangen.geantyref.TypeFactory;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.spongepowered.configurate.ConfigurationNode;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+import org.spongepowered.configurate.serialize.TypeSerializer;
-+
++import java.lang.annotation.Annotation;
++import java.lang.reflect.AnnotatedParameterizedType;
++import java.lang.reflect.AnnotatedType;
 +import java.lang.reflect.ParameterizedType;
 +import java.lang.reflect.Type;
 +import java.util.Collections;
 +import java.util.Map;
 +import java.util.function.Function;
++import org.jspecify.annotations.Nullable;
++import org.spongepowered.configurate.ConfigurationNode;
++import org.spongepowered.configurate.serialize.SerializationException;
++import org.spongepowered.configurate.serialize.TypeSerializer;
 +
 +@SuppressWarnings("rawtypes")
-+public abstract class FastutilMapSerializer<M extends Map<?, ?>> implements TypeSerializer<M> {
-+    private final Function<Map, ? extends M> factory;
++public abstract class FastutilMapSerializer<M extends Map<?, ?>> implements TypeSerializer.Annotated<M> {
 +
-+    protected FastutilMapSerializer(final Function<Map, ? extends M> factory) {
++    private final Function<? super Map, ? extends M> factory;
++
++    protected FastutilMapSerializer(final Function<? super Map, ? extends M> factory) {
 +        this.factory = factory;
 +    }
 +
 +    @Override
-+    public M deserialize(final Type type, final ConfigurationNode node) throws SerializationException {
-+        @Nullable final Map map = (Map) node.get(this.createBaseMapType((ParameterizedType) type));
++    public M deserialize(final AnnotatedType annotatedType, final ConfigurationNode node) throws SerializationException {
++        final Map map = (Map) node.get(this.createAnnotatedMapType((AnnotatedParameterizedType) annotatedType));
 +        return this.factory.apply(map == null ? Collections.emptyMap() : map);
 +    }
 +
 +    @Override
-+    public void serialize(final Type type, @Nullable final M obj, final ConfigurationNode node) throws SerializationException {
++    public void serialize(final AnnotatedType annotatedType, final @Nullable M obj, final ConfigurationNode node) throws SerializationException {
 +        if (obj == null || obj.isEmpty()) {
 +            node.raw(null);
 +        } else {
-+            final Type baseMapType = this.createBaseMapType((ParameterizedType) type);
++            final AnnotatedType baseMapType = this.createAnnotatedMapType((AnnotatedParameterizedType) annotatedType);
 +            node.set(baseMapType, obj);
 +        }
 +    }
 +
++    private AnnotatedType createAnnotatedMapType(final AnnotatedParameterizedType type) {
++        final Type baseType = this.createBaseMapType((ParameterizedType) type.getType());
++        return GenericTypeReflector.annotate(baseType, type.getAnnotations());
++    }
++
 +    protected abstract Type createBaseMapType(final ParameterizedType type);
 +
 +    public static final class SomethingToPrimitive<M extends Map<?, ?>> extends FastutilMapSerializer<M> {
++
 +        private final Type primitiveType;
 +
 +        public SomethingToPrimitive(final Function<Map, ? extends M> factory, final Type primitiveType) {
@@ -2862,6 +2879,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    public static final class PrimitiveToSomething<M extends Map<?, ?>> extends FastutilMapSerializer<M> {
++
 +        private final Type primitiveType;
 +
 +        public PrimitiveToSomething(final Function<Map, ? extends M> factory, final Type primitiveType) {
@@ -2874,6 +2892,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            return TypeFactory.parameterizedClass(Map.class, GenericTypeReflector.box(this.primitiveType), type.getActualTypeArguments()[0]);
 +        }
 +    }
++
++    public static final class SomethingToSomething<M extends Map<?, ?>> extends FastutilMapSerializer<M> {
++
++        public SomethingToSomething(final Function<? super Map, ? extends M> factory) {
++            super(factory);
++        }
++
++        @Override
++        protected Type createBaseMapType(final ParameterizedType type) {
++            return TypeFactory.parameterizedClass(Map.class, type.getActualTypeArguments()[0], type.getActualTypeArguments()[1]);
++        }
++    }
 +}
 diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java
 new file mode 100644
@@ -2885,15 +2915,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import com.mojang.logging.LogUtils;
 +import io.leangen.geantyref.TypeToken;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.slf4j.Logger;
-+import org.spongepowered.configurate.BasicConfigurationNode;
-+import org.spongepowered.configurate.ConfigurationNode;
-+import org.spongepowered.configurate.ConfigurationOptions;
-+import org.spongepowered.configurate.NodePath;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+import org.spongepowered.configurate.serialize.TypeSerializer;
-+
++import java.lang.annotation.Retention;
++import java.lang.annotation.RetentionPolicy;
++import java.lang.reflect.AnnotatedType;
 +import java.lang.reflect.ParameterizedType;
 +import java.lang.reflect.Type;
 +import java.util.Collections;
@@ -2901,27 +2925,45 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.util.LinkedHashMap;
 +import java.util.Map;
 +import java.util.Set;
++import org.jspecify.annotations.Nullable;
++import org.slf4j.Logger;
++import org.spongepowered.configurate.BasicConfigurationNode;
++import org.spongepowered.configurate.ConfigurationNode;
++import org.spongepowered.configurate.ConfigurationOptions;
++import org.spongepowered.configurate.NodePath;
++import org.spongepowered.configurate.serialize.SerializationException;
++import org.spongepowered.configurate.serialize.TypeSerializer;
++import org.spongepowered.configurate.serialize.TypeSerializerCollection;
 +
 +import static java.util.Objects.requireNonNull;
 +
 +/**
 + * Map serializer that does not throw errors on individual entry serialization failures.
 + */
-+public class MapSerializer implements TypeSerializer<Map<?, ?>> {
++public class MapSerializer implements TypeSerializer.Annotated<Map<?, ?>> {
 +
 +    public static final TypeToken<Map<?, ?>> TYPE = new TypeToken<Map<?, ?>>() {};
 +
 +    private static final Logger LOGGER = LogUtils.getClassLogger();
 +
 +    private final boolean clearInvalids;
++    private final TypeSerializer<Map<?, ?>> fallback;
 +
 +    public MapSerializer(boolean clearInvalids) {
 +        this.clearInvalids = clearInvalids;
++        this.fallback = requireNonNull(TypeSerializerCollection.defaults().get(TYPE), "Could not find default Map<?, ?> serializer");
 +    }
 +
++    @Retention(RetentionPolicy.RUNTIME)
++    public @interface ThrowExceptions {}
++
 +    @Override
-+    public Map<?, ?> deserialize(Type type, ConfigurationNode node) throws SerializationException {
++    public Map<?, ?> deserialize(AnnotatedType annotatedType, ConfigurationNode node) throws SerializationException {
++        if (annotatedType.isAnnotationPresent(ThrowExceptions.class)) {
++            return this.fallback.deserialize(annotatedType, node);
++        }
 +        final Map<Object, Object> map = new LinkedHashMap<>();
++        final Type type = annotatedType.getType();
 +        if (node.isMap()) {
 +            if (!(type instanceof ParameterizedType parameterizedType)) {
 +                throw new SerializationException(type, "Raw types are not supported for collections");
@@ -2975,7 +3017,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void serialize(Type type, @Nullable Map<?, ?> obj, ConfigurationNode node) throws SerializationException {
++    public void serialize(AnnotatedType annotatedType, @Nullable Map<?, ?> obj, ConfigurationNode node) throws SerializationException {
++        if (annotatedType.isAnnotationPresent(ThrowExceptions.class)) {
++            this.fallback.serialize(annotatedType, obj, node);
++            return;
++        }
++        final Type type = annotatedType.getType();
 +        if (!(type instanceof ParameterizedType parameterizedType)) {
 +            throw new SerializationException(type, "Raw types are not supported for collections");
 +        }
@@ -3036,7 +3083,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public @Nullable Map<?, ?> emptyValue(Type specificType, ConfigurationOptions options) {
++    public @Nullable Map<?, ?> emptyValue(AnnotatedType specificType, ConfigurationOptions options) {
++        if (specificType.isAnnotationPresent(ThrowExceptions.class)) {
++            return this.fallback.emptyValue(specificType, options);
++        }
 +        return new LinkedHashMap<>();
 +    }
 +
@@ -3055,18 +3105,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import com.google.common.collect.ImmutableTable;
 +import com.google.common.collect.Table;
 +import io.leangen.geantyref.TypeFactory;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import java.lang.reflect.ParameterizedType;
++import java.lang.reflect.Type;
++import java.util.Map;
++import java.util.Objects;
++import org.jspecify.annotations.Nullable;
 +import org.spongepowered.configurate.BasicConfigurationNode;
 +import org.spongepowered.configurate.ConfigurationNode;
 +import org.spongepowered.configurate.ConfigurationOptions;
 +import org.spongepowered.configurate.serialize.SerializationException;
 +import org.spongepowered.configurate.serialize.TypeSerializer;
 +
-+import java.lang.reflect.ParameterizedType;
-+import java.lang.reflect.Type;
-+import java.util.Map;
-+import java.util.Objects;
-+
 +public class TableSerializer implements TypeSerializer<Table<?, ?, ?>> {
 +    private static final int ROW_TYPE_ARGUMENT_INDEX = 0;
 +    private static final int COLUMN_TYPE_ARGUMENT_INDEX = 1;
@@ -3087,13 +3136,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        final Type columnType = type.getActualTypeArguments()[COLUMN_TYPE_ARGUMENT_INDEX];
 +        final Type valueType = type.getActualTypeArguments()[VALUE_TYPE_ARGUMENT_INDEX];
 +
-+        final @Nullable TypeSerializer<R> rowKeySerializer = (TypeSerializer<R>) node.options().serializers().get(rowType);
++        final TypeSerializer<R> rowKeySerializer = (TypeSerializer<R>) node.options().serializers().get(rowType);
 +        if (rowKeySerializer == null) {
 +            throw new SerializationException("Could not find serializer for table row type " + rowType);
 +        }
 +
 +        final Type mapType = TypeFactory.parameterizedClass(Map.class, columnType, valueType);
-+        final @Nullable TypeSerializer<Map<C, V>> columnValueSerializer = (TypeSerializer<Map<C, V>>) node.options().serializers().get(mapType);
++        final TypeSerializer<Map<C, V>> columnValueSerializer = (TypeSerializer<Map<C, V>>) node.options().serializers().get(mapType);
 +        if (columnValueSerializer == null) {
 +            throw new SerializationException("Could not find serializer for table column-value map " + type);
 +        }
@@ -3108,7 +3157,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void serialize(final Type type, @Nullable final Table<?, ?, ?> table, final ConfigurationNode node) throws SerializationException {
++    public void serialize(final Type type, final @Nullable Table<?, ?, ?> table, final ConfigurationNode node) throws SerializationException {
 +        if (table != null) {
 +            this.serialize0(table, (ParameterizedType) type, node);
 +        }
@@ -3120,7 +3169,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        final Type columnType = type.getActualTypeArguments()[COLUMN_TYPE_ARGUMENT_INDEX];
 +        final Type valueType = type.getActualTypeArguments()[VALUE_TYPE_ARGUMENT_INDEX];
 +
-+        final @Nullable TypeSerializer rowKeySerializer = node.options().serializers().get(rowType);
++        final TypeSerializer rowKeySerializer = node.options().serializers().get(rowType);
 +        if (rowKeySerializer == null) {
 +            throw new SerializationException("Could not find a serializer for table row type " + rowType);
 +        }
@@ -3138,6 +3187,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return ImmutableTable.of();
 +    }
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.serializer.collections;
++
++import org.jspecify.annotations.NullMarked;
+diff --git a/src/main/java/io/papermc/paper/configuration/serializer/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/serializer/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.serializer;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -3153,7 +3222,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import net.minecraft.core.RegistryAccess;
 +import net.minecraft.resources.ResourceKey;
 +import net.minecraft.resources.ResourceLocation;
-+import org.checkerframework.checker.nullness.qual.Nullable;
 +import org.spongepowered.configurate.serialize.ScalarSerializer;
 +import org.spongepowered.configurate.serialize.SerializationException;
 +
@@ -3201,7 +3269,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    private ResourceKey<R> deserializeKey(final Object input) throws SerializationException {
-+        final @Nullable ResourceLocation key = ResourceLocation.tryParse(input.toString());
++        final ResourceLocation key = ResourceLocation.tryParse(input.toString());
 +        if (key == null) {
 +            throw new SerializationException("Could not create a key from " + input);
 +        }
@@ -3289,6 +3357,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.registry().getResourceKey(value).orElseThrow();
 +    }
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.serializer.registry;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/transformation/Transformations.java b/src/main/java/io/papermc/paper/configuration/transformation/Transformations.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -3346,6 +3424,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import com.mojang.logging.LogUtils;
 +import io.papermc.paper.configuration.Configuration;
++import java.util.function.Predicate;
 +import net.kyori.adventure.text.Component;
 +import net.kyori.adventure.text.format.NamedTextColor;
 +import net.kyori.adventure.text.minimessage.MiniMessage;
@@ -3353,14 +3432,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket;
 +import org.bukkit.ChatColor;
 +import org.bukkit.configuration.file.YamlConfiguration;
-+import org.checkerframework.checker.nullness.qual.Nullable;
 +import org.slf4j.Logger;
 +import org.spongepowered.configurate.ConfigurationNode;
 +import org.spongepowered.configurate.transformation.ConfigurationTransformation;
 +import org.spongepowered.configurate.transformation.TransformAction;
 +
-+import java.util.function.Predicate;
-+
 +import static org.spongepowered.configurate.NodePath.path;
 +
 +public final class LegacyPaperConfig {
@@ -3425,7 +3501,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            .addAction(path("allow-perm-block-break-exploits"), (path, value) -> new Object[]{"settings", "unsupported-settings", "allow-permanent-block-break-exploits"})
 +            .addAction(path("settings", "unsupported-settings", "allow-tnt-duplication"), TransformAction.rename("allow-piston-duplication"))
 +            .addAction(path("settings", "save-player-data"), (path, value) -> {
-+                final @Nullable Object val = value.raw();
++                final Object val = value.raw();
 +                if (val instanceof Boolean bool) {
 +                    spigotConfiguration.set("players.disable-saving", !bool);
 +                }
@@ -3433,7 +3509,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                return null;
 +            })
 +            .addAction(path("settings", "log-named-entity-deaths"), (path, value) -> {
-+                final @Nullable Object val = value.raw();
++                final Object val = value.raw();
 +                if (val instanceof Boolean bool && !bool) {
 +                    spigotConfiguration.set("settings.log-named-deaths", false);
 +                }
@@ -3461,7 +3537,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            .addAction(path("packet-limiter", "limits", "all"), (path, value) -> new Object[]{"packet-limiter", "all-packets"})
 +            .addAction(path("packet-limiter", "limits"), (path, value) -> new Object[]{"packet-limiter", "overrides"})
 +            .addAction(path("packet-limiter", "overrides", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> {
-+                final @Nullable Object keyValue = value.key();
++                final Object keyValue = value.key();
 +                if (keyValue != null && keyValue.toString().equals("PacketPlayInAutoRecipe")) { // add special cast to handle the default for moj-mapped servers that upgrade the config
 +                    return path.with(path.size() - 1, ServerboundPlaceRecipePacket.class.getSimpleName()).array();
 +                }
@@ -3520,7 +3596,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +    private static void miniMessageWithTranslatable(final ConfigurationTransformation.Builder builder, final Predicate<String> englishCheck, final Component component, final String... strPath) {
 +        builder.addAction(path((Object[]) strPath), (path, value) -> {
-+            final @Nullable Object val = value.raw();
++            final Object val = value.raw();
 +            if (val != null) {
 +                final String strVal = val.toString();
 +                if (!englishCheck.test(strVal)) {
@@ -3535,7 +3611,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    private static void miniMessage(final ConfigurationTransformation.Builder builder, final String... strPath) {
 +        builder.addAction(path((Object[]) strPath), (path, value) -> {
-+            final @Nullable Object val = value.raw();
++            final Object val = value.raw();
 +            if (val != null) {
 +                value.set(miniMessage(val.toString()));
 +            }
@@ -3565,6 +3641,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        });
 +    }
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.transformation.global;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/V29_LogIPs.java b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/V29_LogIPs.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -3576,7 +3662,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.util.Properties;
 +import net.minecraft.server.MinecraftServer;
 +import net.minecraft.server.dedicated.DedicatedServer;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.spongepowered.configurate.ConfigurateException;
 +import org.spongepowered.configurate.ConfigurationNode;
 +import org.spongepowered.configurate.NodePath;
@@ -3615,6 +3701,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.transformation.global.versioned;
++
++import org.jspecify.annotations.NullMarked;
+diff --git a/src/main/java/io/papermc/paper/configuration/transformation/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/transformation/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.transformation;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java b/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -3633,7 +3739,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import net.minecraft.resources.ResourceLocation;
 +import net.minecraft.server.MinecraftServer;
 +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.slf4j.Logger;
 +import org.spongepowered.configurate.ConfigurateException;
 +import org.spongepowered.configurate.ConfigurationNode;
@@ -3702,6 +3808,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import io.papermc.paper.configuration.Configuration;
 +import io.papermc.paper.configuration.WorldConfiguration;
++import java.util.HashMap;
++import java.util.List;
++import java.util.Locale;
++import java.util.Map;
++import java.util.Optional;
 +import net.minecraft.core.Holder;
 +import net.minecraft.core.registries.BuiltInRegistries;
 +import net.minecraft.core.registries.Registries;
@@ -3710,16 +3821,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import net.minecraft.world.entity.MobCategory;
 +import net.minecraft.world.item.Item;
 +import org.bukkit.Material;
-+import org.checkerframework.checker.nullness.qual.Nullable;
 +import org.spongepowered.configurate.transformation.ConfigurationTransformation;
 +import org.spongepowered.configurate.transformation.TransformAction;
 +
-+import java.util.HashMap;
-+import java.util.List;
-+import java.util.Locale;
-+import java.util.Map;
-+import java.util.Optional;
-+
 +import static io.papermc.paper.configuration.transformation.Transformations.moveFromRoot;
 +import static io.papermc.paper.configuration.transformation.Transformations.moveFromRootAndRename;
 +import static org.spongepowered.configurate.NodePath.path;
@@ -3758,14 +3862,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            }).build())
 +            .addVersion(19, ConfigurationTransformation.builder()
 +                .addAction(path("anti-xray", "hidden-blocks"), (path, value) -> {
-+                    @Nullable final List<String> hiddenBlocks = value.getList(String.class);
++                    final List<String> hiddenBlocks = value.getList(String.class);
 +                    if (hiddenBlocks != null) {
 +                        hiddenBlocks.remove("lit_redstone_ore");
 +                    }
 +                    return null;
 +                })
 +                .addAction(path("anti-xray", "replacement-blocks"), (path, value) -> {
-+                    @Nullable final List<String> replacementBlocks = value.getList(String.class);
++                    final List<String> replacementBlocks = value.getList(String.class);
 +                    if (replacementBlocks != null) {
 +                        final int index = replacementBlocks.indexOf("planks");
 +                        if (index != -1) {
@@ -3838,9 +3942,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    value.childrenMap().forEach((key, node) -> {
 +                        String itemName = key.toString();
 +                        final Optional<Holder.Reference<Item>> itemHolder = BuiltInRegistries.ITEM.get(ResourceKey.create(Registries.ITEM, ResourceLocation.parse(itemName.toLowerCase(Locale.ROOT))));
-+                        final @Nullable String item;
++                        final String item;
 +                        if (itemHolder.isEmpty()) {
-+                            final @Nullable Material bukkitMat = Material.matchMaterial(itemName);
++                            final Material bukkitMat = Material.matchMaterial(itemName);
 +                            item = bukkitMat != null ? bukkitMat.getKey().getKey() : null;
 +                        } else {
 +                            item = itemHolder.get().unwrapKey().orElseThrow().location().getPath();
@@ -3976,7 +4080,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +        builder.addAction(path("feature-seeds", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> {
 +            final String key = path.array()[path.size() - 1].toString();
-+            if (!key.equals("generate-random-seeds-for-all")) {
++            if (!"generate-random-seeds-for-all".equals(key)) {
 +                return new Object[]{"feature-seeds", "features", key};
 +            }
 +            return null;
@@ -3994,7 +4098,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        });
 +
 +        builder.addAction(path("redstone-implementation"), (path, value) -> {
-+            if (value.require(String.class).equalsIgnoreCase("alternate-current")) {
++            if ("alternate-current".equalsIgnoreCase(value.require(String.class))) {
 +                value.set("alternate_current");
 +            }
 +            return new Object[]{"misc", "redstone-implementation"};
@@ -4020,6 +4124,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        moveFromRootAndRename(builder, path("game-mechanics", oldKey), newKey, parents);
 +    }
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.transformation.world;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V29_ZeroWorldHeight.java b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V29_ZeroWorldHeight.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -4029,7 +4143,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +package io.papermc.paper.configuration.transformation.world.versioned;
 +
 +import io.papermc.paper.configuration.type.number.IntOr;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.spongepowered.configurate.ConfigurateException;
 +import org.spongepowered.configurate.ConfigurationNode;
 +import org.spongepowered.configurate.NodePath;
@@ -4116,7 +4230,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import io.papermc.paper.configuration.Configurations;
 +import net.minecraft.world.level.GameRules;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.spongepowered.configurate.ConfigurationNode;
 +import org.spongepowered.configurate.NodePath;
 +import org.spongepowered.configurate.transformation.ConfigurationTransformation;
@@ -4167,6 +4281,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        }
 +    }
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.transformation.world.versioned;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/type/BooleanOrDefault.java b/src/main/java/io/papermc/paper/configuration/type/BooleanOrDefault.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -4175,14 +4299,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.configuration.type;
 +
-+import org.apache.commons.lang3.BooleanUtils;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.spongepowered.configurate.serialize.ScalarSerializer;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+
 +import java.lang.reflect.Type;
 +import java.util.Locale;
 +import java.util.function.Predicate;
++import org.apache.commons.lang3.BooleanUtils;
++import org.jspecify.annotations.Nullable;
++import org.spongepowered.configurate.serialize.ScalarSerializer;
++import org.spongepowered.configurate.serialize.SerializationException;
 +
 +public record BooleanOrDefault(@Nullable Boolean value) {
 +    private static final String DEFAULT_VALUE = "default";
@@ -4217,7 +4340,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +        @Override
 +        protected Object serialize(BooleanOrDefault item, Predicate<Class<?>> typeSupported) {
-+            final @Nullable Boolean value = item.value;
++            final Boolean value = item.value;
 +            if (value != null) {
 +                return value.toString();
 +            } else {
@@ -4236,7 +4359,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import io.papermc.paper.configuration.type.number.IntOr;
 +import java.lang.reflect.Type;
-+import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jspecify.annotations.Nullable;
 +import org.spongepowered.configurate.ConfigurationNode;
 +import org.spongepowered.configurate.serialize.SerializationException;
 +import org.spongepowered.configurate.serialize.TypeSerializer;
@@ -4349,20 +4472,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.configuration.type;
 +
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.spongepowered.configurate.serialize.ScalarSerializer;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+
 +import java.lang.reflect.Type;
 +import java.util.Objects;
 +import java.util.function.Predicate;
 +import java.util.regex.Pattern;
++import org.jspecify.annotations.Nullable;
++import org.spongepowered.configurate.serialize.ScalarSerializer;
++import org.spongepowered.configurate.serialize.SerializationException;
 +
 +public final class Duration {
 +
 +    private static final Pattern SPACE = Pattern.compile(" ");
 +    private static final Pattern NOT_NUMERIC = Pattern.compile("[^-\\d.]");
-+    public static final Serializer SERIALIZER = new Serializer();
++    public static final ScalarSerializer<Duration> SERIALIZER = new Serializer();
 +
 +    private final long seconds;
 +    private final String value;
@@ -4752,17 +4874,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.configuration.type.fallback;
 +
-+import net.minecraft.server.MinecraftServer;
-+import org.checkerframework.checker.nullness.qual.Nullable;
-+import org.spigotmc.SpigotWorldConfig;
-+import org.spongepowered.configurate.serialize.ScalarSerializer;
-+import org.spongepowered.configurate.serialize.SerializationException;
-+
 +import java.lang.reflect.Type;
 +import java.util.HashMap;
 +import java.util.Map;
 +import java.util.function.Predicate;
 +import java.util.function.Supplier;
++import net.minecraft.server.MinecraftServer;
++import org.spigotmc.SpigotWorldConfig;
++import org.spongepowered.configurate.serialize.ScalarSerializer;
++import org.spongepowered.configurate.serialize.SerializationException;
 +
 +import static io.leangen.geantyref.GenericTypeReflector.erase;
 +
@@ -4789,7 +4909,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    @Override
 +    public FallbackValue deserialize(Type type, Object obj) throws SerializationException {
-+        final @Nullable FallbackCreator<?> creator = REGISTRY.get(erase(type));
++        final FallbackCreator<?> creator = REGISTRY.get(erase(type));
 +        if (creator == null) {
 +            throw new SerializationException(type + " does not have a FallbackCreator registered");
 +        }
@@ -4821,6 +4941,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return value < 0 ?  OptionalInt.empty() : OptionalInt.of(value);
 +    }
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java b/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.type.fallback;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/io/papermc/paper/configuration/type/number/BelowZeroToEmpty.java b/src/main/java/io/papermc/paper/configuration/type/number/BelowZeroToEmpty.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -5073,6 +5203,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    protected abstract boolean belowZero(O value);
 +}
+diff --git a/src/main/java/io/papermc/paper/configuration/type/number/package-info.java b/src/main/java/io/papermc/paper/configuration/type/number/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/type/number/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.type.number;
++
++import org.jspecify.annotations.NullMarked;
+diff --git a/src/main/java/io/papermc/paper/configuration/type/package-info.java b/src/main/java/io/papermc/paper/configuration/type/package-info.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/configuration/type/package-info.java
+@@ -0,0 +0,0 @@
++@NullMarked
++package io.papermc.paper.configuration.type;
++
++import org.jspecify.annotations.NullMarked;
 diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/server/Main.java
diff --git a/patches/server/Remap-reflection-calls-in-plugins-using-internals.patch b/patches/server/Remap-reflection-calls-in-plugins-using-internals.patch
index fb1700bad4..6dc4f9b842 100644
--- a/patches/server/Remap-reflection-calls-in-plugins-using-internals.patch
+++ b/patches/server/Remap-reflection-calls-in-plugins-using-internals.patch
@@ -32,8 +32,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  import io.papermc.paper.configuration.serializer.collections.MapSerializer;
 +import io.papermc.paper.util.MappingEnvironment;
  import io.papermc.paper.util.ObfHelper;
- import net.minecraft.network.protocol.Packet;
- import org.checkerframework.checker.nullness.qual.Nullable;
+ import java.lang.reflect.Type;
+ import java.util.List;
 @@ -0,0 +0,0 @@ public final class PacketClassSerializer extends ScalarSerializer<Class<? extend
      @Override
      protected @Nullable Object serialize(final Class<? extends Packet<?>> packetClass, final Predicate<Class<?>> typeSupported) {