Burst exists to compile a small, predictable subset of C# to fast native code. When the Burst compiler sees a managed type or unsupported API inside a [BurstCompile] context, it stops with BC1016 (wording can vary slightly by Unity/Burst version, but the intent is always the same: this type is not allowed here).
This guide explains what BC1016 means, how to locate the exact line, and how to refactor toward Burst-compatible data without giving up Jobs or Entities workflows.
Problem summary
Typical console / build output
error BC1016: ... managed type ... not supported- Or Burst diagnostics that name a class,
string,object,List<T>,Dictionary, or a UnityEngine.Object derived type inside Burst code.
When it shows up
- Compiling an
IJob,IJobParallelFor,IJobEntity, or a static method marked[BurstCompile]. - Upgrading Burst, Entities, or Unity and suddenly a previously “working” pattern is rejected.
- Copy-pasting MonoBehaviour-style code into a job without changing data types.
Impact
- Player builds and sometimes the editor fail Burst compilation.
- You cannot schedule the job until the error is fixed, blocking performance work.
Why this happens
Burst only supports blittable and unmanaged data layouts and a whitelist of APIs. Common triggers for BC1016 include:
- Reference types (
class,string, boxed values,object) - Managed collections (
List<T>,Dictionary<,>,Queue<T>) - UnityEngine.Object references (
GameObject,Transform,Material,Mesh,Texture,Component) - Managed arrays of reference types (
string[],MyClass[]) - Calling managed-only Unity APIs from Burst code
Burst is strict by design. If you need managed behavior, keep it outside the Burst entry point and pass only plain data in.
Fix - Step 1 - Read the full Burst error line
Open the Console and double-click the BC1016 entry. Note:
- the source file and line number
- the type name Burst complains about
That type is your refactor target.
Fix - Step 2 - Remove reference types from the job struct
Pattern A - string in a job
Burst cannot use string. Replace with:
- a fixed string (
FixedString32Bytes,FixedString64Bytes,FixedString128Bytes, etc.) fromUnity.Collections, or - an integer id that maps to strings in managed code after the job completes
Pattern B - List<T> or Dictionary
Use:
NativeList<T>NativeHashMap<TKey, TValue>NativeArray<T>
Remember to Dispose them in OnDestroy / Dispose patterns or use Allocator.TempJob with explicit disposal in the same frame when appropriate.
Pattern C - MyClass fields on the job
Convert hot data to struct with unmanaged fields, or store indices into a NativeArray or BufferLookup in Entities code.
Fix - Step 3 - Replace managed arrays with NativeArray
Example direction (not a drop-in for every project):
// Not Burst-safe
// public string[] names;
// Burst-safe (example shape)
public NativeArray<FixedString64Bytes> names;
If you only need numeric data, prefer NativeArray<float> or NativeArray<int> and translate results on the main thread.
Fix - Step 4 - Move UnityEngine.Object work to the main thread
You cannot call Transform.position, Instantiate, Debug.Log (in many setups), or most UnityEngine APIs from inside Burst.
Split the work:
- Burst job reads/writes pure numeric or struct data in native collections.
- After
Complete()(or using a system that consumes results), apply transforms, spawn objects, or update UI on the main thread.
Fix - Step 5 - Check BurstCompile on the wrong method
Sometimes BC1016 appears because [BurstCompile] was added to a helper that still uses managed utilities.
- Remove
[BurstCompile]from methods that must stay managed, or - Split into
BurstCompileand non-Burst partials
Verification
After changes:
- Clear console and reimport or recompile scripts.
- Run Enter Play Mode with the job scheduled.
- Confirm no BC1016 in the console.
- Optional - enable Burst AOT Settings diagnostics for your target platform and run a development build to catch platform-specific rejections early.
Alternative fixes and edge cases
- Entities 1.x / 2.x - Prefer generated aspects and
RefRO/RefRWto data instead of holding managed handles in systems. Keep generated code paths Burst-safe. - BurstDiscard - Use
[BurstDiscard]only for debug hooks you truly need; it does not make managed types safe inside hot loops. - Shared static managed state - Not Burst-safe. Pass data explicitly through job fields.
Prevention tips
- Treat job structs as plain data carriers - if a field feels “object oriented,” it probably is not Burst-safe.
- Add a code review rule: no
string,class, orUnityEngine.Objectfields insideIJob*structs. - When prototyping, start managed, then extract a Burst core once the algorithm stabilizes.
FAQ
Does BC1016 mean Burst is broken?
No. It means the compiler is doing its job. The fix is almost always data layout and API choice.
Can I use bool?
Often yes in structs, but prefer explicit sizing (byte flags) when you need deterministic layout across platforms.
What about float3 from Mathematics?
Unity.Mathematics types are generally Burst-friendly. Prefer them over Vector3 inside Burst jobs.
I only use MonoBehaviour, not DOTS. Can I still hit BC1016?
Yes, if you use the Jobs package with [BurstCompile] on jobs or static methods.
Related reading
- Unity manual - Burst Compiler overview and supported features (search from docs.unity3d.com).
- Our Unity DOTS overview chapter and Writing Burst-Optimized Jobs for Gameplay for broader context.
- Data-oriented design in Unity - when and why use DOTS for a higher-level pipeline discussion.
- If loads fail after refactors, see Unity Addressables Invalid Key at Runtime (separate issue, but common in the same shipping week).
Bookmark this page the first time Burst blocks your build so you can jump straight to the checklist. Share it with anyone on your team who is new to Jobs or Entities.