Unity IL2CPP Build Fails with Symbol Not Found - Stripping and Link Fix
Problem: A Unity IL2CPP build fails during or after native compilation with errors such as undefined reference to, symbol not found, unresolved external symbol (MSVC LNK2019), or Unity Console messages that mention UnityLinker, managed code stripping, or a missing native function your C# code calls through DllImport or a plugin. The Editor may run fine because stripping and full IL2CPP linking only apply to player builds.
Root cause: IL2CPP converts managed code to C++ then your platform toolchain links a final binary. Failures usually come from: (1) Managed code stripping removed types or methods still needed at runtime (often via reflection, serialization, or plugins); (2) a native library is missing, not copied for the target architecture, or not linked; (3) name mangling or calling convention mismatches on native exports; (4) duplicate or conflicting native symbols across plugins. Fixing it means aligning stripping rules with what the build actually needs and verifying native plugin layout.
This guide walks you from fastest checks to deeper linker and stripping fixes.
Quick Fix Checklist
- Strip less – In Edit > Project Settings > Player > Other Settings, set Managed Stripping Level to Low (or Minimal) for the failing platform and rebuild. If the build succeeds, stripping was removing required code.
- Preserve types – Add a link.xml (or Preserve attributes) for assemblies, types, or methods that must survive stripping (see Solution 2).
- Native plugins – Confirm the plugin .meta enables the right platforms and CPU (ARM64, x86_64). Confirm the binary exists for the architecture you build.
- Compare backends – Build once with Mono (where allowed). If Mono works and IL2CPP fails with symbol errors, focus on stripping and native IL2CPP paths.
Solution 1: Confirm the exact failing phase
Symptom: You only see a generic “Build failed” message.
Step 1: Open the Editor log (Unity Hub or Help > Open Editor Log) or the Player build log Unity prints for your platform.
Step 2: Search for undefined, unresolved, LNK2019, ld:, or UnityLinker.
Step 3: If the message names a C# type or method, treat it as managed stripping. If it names a .so, .a, .lib, or a raw C symbol, treat it as native linking (Solution 3).
Verification: You have one clear category before changing ten settings at once.
Solution 2: Managed stripping removed code (link.xml and Preserve)
Symptom: Log mentions UnityLinker, Strip, or a missing managed type that you only use through reflection, JsonUtility, SendMessage, Addressables, or third-party SDKs that discover types by name.
Step 1: Temporarily set Managed Stripping Level to Minimal for the platform under Player Settings and rebuild.
Step 2: If that fixes the build, add a permanent Assets/link.xml so you can raise stripping again later:
<linker>
<assembly fullname="YourAssemblyName" preserve="all"/>
<assembly fullname="UnityEngine">
<type fullname="UnityEngine.SomeType" preserve="all"/>
</assembly>
</linker>
Replace assembly and type names with what the error or your SDK docs require. Many plugins ship a link.xml; ensure it is under Assets and included in the build.
Step 3: For small surfaces, you can mark types or methods with [Preserve] (UnityEngine.Scripting) or use [RequireAttributeUsages] patterns recommended by the package vendor.
Step 4: Rebuild with your desired stripping level (e.g. Low or Medium) and confirm the error stays gone.
Verification: IL2CPP build completes and the previously missing feature works in a Release player build, not only in the Editor.
Solution 3: Native plugin and symbol mismatch
Symptom: Linker errors reference DllImport names, __Internal, or a .cpp file under Il2CppOutputProject that calls a missing native function.
Step 1: In the Project window, select your .so / .dll / .a / .bundle plugin and inspect the Inspector:
- Select platforms for plugin matches your build (e.g. Android, iOS, Windows).
- CPU matches ARM64 vs x86_64 as appropriate.
- Load on startup or Editor / Standalone flags match where you need the library.
Step 2: On Android, confirm Player Settings > Publishing Settings and Target Architectures include the ABI your .so provides. A common failure is shipping only arm64-v8a while the plugin folder only contains armeabi-v7a, or the reverse.
Step 3: On iOS, confirm the native library is added to the Xcode project (Unity usually handles this). Watch for bitcode or minimum iOS mismatches per plugin documentation.
Step 4: Ensure DllImport entry points exactly match exported symbol names (including stdcall / cdecl on Windows). For __Internal, the symbol must be linked from a static library included in the iOS Xcode project.
Verification: Clean build folder, rebuild, and confirm the linker command line (in detailed logs) lists the expected native library.
Solution 4: IL2CPP and incremental cache corruption
Symptom: The same project built yesterday; today link fails after a Unity or package upgrade.
Step 1: Close Unity, delete Library/Il2cppBuildCache (and optionally Library/Bee) inside the project, reopen, and rebuild.
Step 2: If you use custom CMake or Gradle hooks, diff them against a fresh Unity template for your version.
Verification: First IL2CPP build is slower but completes without stale object files.
Prevention Tips
- After adding a new analytics, ads, or networking SDK, run an IL2CPP Release build on your real target device before milestone week.
- Keep link.xml changes in version control with a one-line comment explaining which stripped type caused the crash.
- Document native plugin versions and ABIs next to the files in Plugins/ so art and code leads do not overwrite mismatched binaries.
Alternative Approaches
- Mono scripting backend (desktop only for many games): Use temporarily to unblock QA while you fix IL2CPP stripping or native linkage.
- Disable bitcode or adjust Xcode settings only when Apple and your plugin vendor allow it; prefer updating the plugin first.
Related Links
- Unity Build Fails with Scripting Backend Error - Complete Solution
- Unity Build Fails with Error CS0246 Type or Namespace Not Found - Assembly Fix
- Unity 2026.6 LTS Build Hangs at 90 Percent Progress Bar - Fix
- Unity Guide – Player Settings and build pipeline context
Official references: Unity Manual sections on IL2CPP, Managed bytecode stripping, and Native plug-ins.
Bookmark this page the first time you see a linker symbol error after enabling High stripping or adding a native SDK. Share it with teammates who ship IL2CPP to Android or iOS so everyone uses the same stripping and plugin checklist.
FAQ
Does Minimal stripping fix performance?
It trades larger builds for fewer stripping surprises. After things work, raise the level gradually and keep link.xml tight.
Why does Editor work but IL2CPP fails?
The Editor uses Mono and does not run the same linker and stripper path as a player build.
Can Burst cause symbol errors?
Usually you see Burst compilation errors instead, but mixed native stacks can interact. If Burst is in the log, fix Burst compile first, then revisit linking.
Should I disable IL2CPP?
For stores that require IL2CPP (typical mobile and console), no. Fix stripping and native plugins instead.