Unity IL2CPP Bug: Code Stripping Removing Classes That Should Be Kept

Unity Reflection Probe Flickering Bug
Unity Reflection Probe Flickering Bug: Causes and Reliable Fixes
February 18, 2026
How to Make a Chain in Unity
How to Make a Chain in Unity (Realistic Physics Chain Tutorial)
February 18, 2026
Unity Reflection Probe Flickering Bug
Unity Reflection Probe Flickering Bug: Causes and Reliable Fixes
February 18, 2026
How to Make a Chain in Unity
How to Make a Chain in Unity (Realistic Physics Chain Tutorial)
February 18, 2026

Unity IL2CPP Bug: Code Stripping Removing Classes That Should Be Kept

You switch your project to IL2CPP, make a build, and suddenly features stop working. The Editor runs fine. Mono builds run fine. But the IL2CPP build throws MissingMethodException, MissingFieldException, or simply behaves as if certain classes do not exist.

This is usually not a random engine failure. It is managed code stripping removing code that Unity believes is unused.

What IL2CPP Actually Does

When using IL2CPP, Unity converts your C# code into C++ and then compiles it into native binaries. During this process, Unity analyzes your assemblies and strips out anything it thinks is not referenced.

The issue appears when code is accessed dynamically instead of directly.

Typical Symptoms

  • MissingMethodException in IL2CPP builds only
  • Reflection-based systems failing
  • JSON deserialization returning empty objects
  • Dependency Injection frameworks not resolving types
  • Addressables or runtime-loaded types failing silently

If it works in the Editor but breaks only in IL2CPP, stripping should be your first suspicion.

Why Unity Strips Needed Code

Unity’s stripping system looks for static references. It cannot reliably detect:

  • Reflection-based method calls
  • Generic types created dynamically
  • Types referenced only inside serialized data
  • Methods invoked by string name

If a type is never directly referenced in compiled code, Unity may remove it.

Fix 1: Use the Preserve Attribute

Unity provides the Preserve attribute to explicitly prevent stripping.

using UnityEngine.Scripting;

[Preserve]
public class RuntimeLoadedClass
{
    [Preserve]
    public void Execute()
    {
        Debug.Log("This method will not be stripped.");
    }
}

This ensures the class and its members are kept during build.

Use this for:

  • Reflection-heavy systems
  • JSON model classes
  • Plugin interfaces

Fix 2: Create a link.xml File

For larger systems, link.xml gives more control.

Create a file named link.xml in your Assets folder.

<linker>
  <assembly fullname="Assembly-CSharp">
    <type fullname="MyNamespace.RuntimeLoadedClass" preserve="all"/>
  </assembly>
</linker>

This tells Unity’s linker to preserve the specified type.

You can also preserve entire assemblies if needed.

Fix 3: Lower Managed Stripping Level

Go to:

Player Settings → Other Settings → Managed Stripping Level

Set it temporarily to Low.

If the build works on Low but fails on Medium or High, you have confirmed a stripping issue.

Keep in mind that lower stripping increases build size.

Fix 4: Force Generic Type Usage

Generic types instantiated dynamically are often removed.

Problem example:

Type genericType = typeof(MyGenericClass<>).MakeGenericType(runtimeType);

Unity may strip the concrete version of that generic class.

Safe workaround:

private static void ForceGenericReference()
{
    var unused = new MyGenericClass<int>();
}

This forces Unity to generate and keep that generic specialization.

Common JSON Serialization Case

Example data model:

[System.Serializable]
public class PlayerData
{
    public int level;
    public string playerName;
}

If this class is only referenced via reflection during deserialization, IL2CPP may strip it.

Solution:

  • Add [Preserve] to the class
  • Reference it directly somewhere in code
  • Use link.xml

How to Confirm It Is Stripping

  • Switch scripting backend to Mono and test
  • Set Managed Stripping Level to Low
  • Rebuild and compare behavior

If the issue disappears under Mono or Low stripping, you have identified the cause.

Best Practices for IL2CPP Projects

  • Test IL2CPP builds early in development
  • Minimize heavy runtime reflection
  • Use Preserve attributes intentionally
  • Maintain a link.xml for third-party frameworks
  • Be cautious with generics and dynamic loading

Is This a Unity Bug?

It feels like one, but technically it is an aggressive optimization system doing its job. The real problem is that dynamic architectures and reflection-based designs are difficult for static analysis.

Final Thoughts

The IL2CPP stripping issue is one of the most common “works in Editor but not in build” problems. Once you understand how managed stripping works, the issue becomes predictable and preventable.

Whenever functionality disappears in an IL2CPP build, always think about reflection, generics, and serialization first. Controlling the linker deliberately will save you from painful last-minute build failures.

Leave a Reply

Your email address will not be published. Required fields are marked *


Skip to toolbar