Skip to content

Reference

Troubleshooting

Symptom → cause → fix for the common issues after obfuscation: missing members, serialization, XAML binding, reflection, SmartScreen, strong names and more.

Most issues come down to one thing — something resolved by name at runtime was renamed. This page maps symptoms to fixes. If yours isn’t here, contact us with the exception and your config.

How to find the culprit fast (bisect)

When a protected build misbehaves, narrow it down by turning passes off one at a time and re-testing:

  1. Rename off ("renameIdentifiers": false) — if the problem disappears, it’s a name resolved at runtime → preserve it (see below). This is by far the most common cause.
  2. Control-flow off ("controlFlowObfuscation": false) — if that fixes it, tell us with the method; control-flow is behaviour-preserving by design, so we want to see it.
  3. Strings off ("encryptStrings": false) — rarely the cause; strings decrypt to identical values.

Whichever pass “fixes” it tells you the category. Then re-enable it and apply a targeted exclusion instead of leaving the pass off.

Runtime errors

SymptomCauseFix
MissingMethodException / MissingFieldException / TypeLoadException at runtimeA member found by reflection/name was renamedPreserve it: exclude, [System.Reflection.Obfuscation], or preservePublicApi. See Keeping your app working.
Type.GetType("MyApp.Foo") returns nullThe type was renamedPreserve that type (exclude), or change the code to typeof(Foo) (identity, rename-safe).
JSON/XML has odd field names, or deserialization returns nullsDTO property names were renamedPreserve the DTOs (attributes are auto-detected; otherwise exclude).
WPF/MAUI: binding errors in the log, blank or dead UIView-model or bound members renamedPreserve view-models + bound members; keep preservePublicApi.
DI: “unable to resolve service” / convention registration finds nothingAssembly-scanning by name hit renamed typesPreserve the scanned types, or register by type.
EF Core: wrong columns / migration mismatchEntity property names renamedPreserve entities, or use explicit HasColumnName.
TypeInitializationException mentioning a Nebula trialThe assembly was built with a trial licenseRebuild with a paid license — trial builds warn and stop after the trial date by design.

Distribution & signing

SymptomCauseFix
“Windows protected your PC” / “Unknown publisher” (SmartScreen)The installer/exe isn’t code-signed yetSign with an Authenticode certificate, or install via the Microsoft Store (Microsoft-signed). Reputation also builds over time. See Installation.
Antivirus flags a freshly obfuscated binaryNew/unsigned binaries have no reputationSign it (Authenticode), submit a false-positive report to the vendor if needed.
Strong-named assembly fails to load / “signature not valid”Obfuscation rewrote the assembly after signingLet Nebula re-sign: set strongNameKeyFile (signing happens after obfuscation).
Single-file build not tamper-protectedAnti-tamper’s self-hash no-ops in a single-file bundle (no on-disk path)Expected — use control-flow + string encryption there, or ship multi-file to keep anti-tamper.

Build / CI

SymptomCauseFix
Build integration does nothing on a dev boxNebulaObfuscate isn’t set there (by design)Set it only on the build agent — see MSBuild & CI.
“build integration is a licensed feature”Free edition is CLI/GUI onlyProvide a license on the build machine (NEBULA_LICENSE, licenseFile, or NebulaLicenseFile).
Non-zero exit / config error in CIBad config or missing inputCheck the exit code and the log; validate paths in nebula.config.json.

Reading an obfuscated crash

A production stack trace full of renamed names can be translated back with the symbol map from the build:

nebula deobfuscate --map protected/MyApp.symbols.json --input crash.txt

See De-obfuscating stack traces. Keep the *.symbols.json from each release build for exactly this.

Diagnosing why a method didn’t flatten

Control-flow leaves a method un-flattened only when it can’t prove the transform is safe (it never emits broken IL). To see why, set the environment variable and run the CLI:

NEBULA_CF_DEBUG=1

It prints, per method, whether each scope flattened or why it was skipped — useful when you expected a specific method (e.g. a license check) to be flattened.

Performance

Renaming and string encryption have negligible runtime cost. Control-flow flattening adds some overhead per transformed method, so for hot paths scope it with controlFlowInclude/controlFlowExclude or a lower controlFlowIntensity rather than flattening everything.