# Protected Application Does Not Start

If your application does not start, closes immediately, or fails during initialization after protection, first check which files are being executed and whether the deployment is complete. Then isolate the protection setting that triggers the failure.

A very common cause is Obfuscation (renaming) combined with reflection. However, missing dependencies, mismatched output files, public-type renaming, serialization, and trimming can produce similar symptoms. Follow the steps below rather than changing several settings at once.

# 1. Use the complete .NET Reactor output

Use the protected assemblies together with the corresponding runtime files produced by the same .NET Reactor run. Do not copy only the protected main DLL into an otherwise unchanged deployment and assume that the original companion files still match.

# Why are there additional .exe, .deps.json, and .runtimeconfig.json files?

A typical Windows .NET 5 or later application published with an application host consists of a managed DLL containing the application code and a native .exe used to launch it. Not every publishing mode produces the same external files. See Microsoft's .NET publishing overview.

For a regular folder deployment, the relevant files commonly include:

File Purpose
MyApp.dll Contains the application's managed code. Use the protected version.
MyApp.exe The native application host that launches the managed application.
MyApp.deps.json Describes the application's dependencies.
MyApp.runtimeconfig.json Contains runtime requirements and configuration.

The JSON files are part of the .NET publish output, not disposable build metadata.

If .NET Reactor finds the corresponding application host .exe next to the input assembly, it copies that host to the output directory. This allows the application to be tested directly from the output directory. If a code-signing certificate is configured in .NET Reactor, the application host can also be signed.

The corresponding .deps.json and .runtimeconfig.json files are carried over as well. Depending on the selected protection and merging settings, .NET Reactor may need to modify them to match the protected application.

This handling applies when the corresponding files already exist in the input directory. .NET Reactor should not create these companion files when they did not exist in the input in the first place. Their absence is not automatically an error: for example, an application can be published without an apphost, or runtime configuration can be contained inside a single-file bundle.

# Check the remaining files and directory structure

Check that all dependencies and application data required at startup are available: additional managed assemblies, native libraries, configuration files, resource and language folders, plug-ins, and any required application license file. Preserve the expected relative paths.

Do not assume that every content file in your application is copied merely because its main assembly was protected. Add required external files that .NET Reactor did not produce from the same input build, without overwriting files it did produce. Do not mix files from different builds or indiscriminately copy the original publish directory over the protected output.

For .NET Framework applications, also retain the required application configuration, such as MyApp.exe.config, and any binding configuration used by the application.

# Single-file applications and embedded assemblies

For a single-file application, run the new protected bundle created by .NET Reactor, not the original published executable. .NET Reactor also creates subfolders containing the individual protected assemblies for inspection. These inspection copies are not separate runtime dependencies and should not be added beside the bundle to make it start. Retain any external content or native files that your publishing configuration actually requires. See Single-File Publishing.

Assemblies configured with Embed Assemblies belong inside the main assembly. They should not remain as separate dependency files in the final deployment. Do not restore their original DLLs as a workaround. If you temporarily disable embedding for a diagnostic test, that test instead needs the normal external dependency files.

# Installers and build integration

If protection runs during the build and a setup package is created afterwards, install that package into a clean test location. Test and inspect the installed application, not only the intermediate protection output.

If the application works from the complete .NET Reactor output but fails after installation, compare the installed files, directory layout, configuration, permissions, and launch location. Check that packaging did not omit dependencies, restore original companion files, or mix protected and unprotected assemblies. See Verify Protected Output.

# 2. Confirm the baseline and collect the actual error

Verify that the unprotected application works in the same environment, using the same build configuration, target framework, architecture, publishing mode, user account, and required input data. A successful run inside the IDE alone is not a sufficient comparison.

Test the actual protected executable or deployment directly. Avoid dotnet run or an IDE action that rebuilds the project and replaces the files you intended to test.

Start the application from a terminal where practical, and collect its console output, exit code, application logs, and any displayed error message. For Windows GUI applications that close without showing a message, also check Event Viewer → Windows Logs → Application for a corresponding error. Not every early failure produces console output or a managed exception.

If an exception is available, collect the complete exception and its inner exceptions, not only the top-level message. For example, a TypeInitializationException can wrap the actual failure in a static constructor. Translate renamed stack-trace entries using the mapping file from the exact protection run. See Debugging Stack Traces.

# Check command-line licensing and protection results

When using a licensed .NET Reactor installation through the command line, always include -licensed. A protection log is also useful:

dotNET_Reactor.Console.exe -licensed -project "C:\Build\MyApp.nrproj" -logfile "C:\Build\reactor.log"

If .NET Reactor is not running as a licensed full version, -licensed prevents protection and returns exit code 101. This guards against accidentally creating demo-protected output on a misconfigured build machine. Make the build stop on a nonzero exit code, and do not test or package stale files left over from an earlier run.

This checks the license of .NET Reactor itself, not the license of your application. See Command Line Parameters and Activation Troubleshooting.

# 3. Isolate the protection setting

Once the deployment is complete and the unprotected application works, use a separate diagnostic copy of your .NET Reactor project:

  1. Disable all protection options. Keep the input assemblies, target platform, and required deployment layout unchanged. Check separately that any configured application license requirements or evaluation locks are satisfied. Disable those only in your private diagnostic configuration when necessary.
  2. Generate fresh output and test it. Use a clean output directory and the original, unprotected inputs. Never use an already protected assembly as the input for the next test.
  3. Enable one feature at a time. Start with Obfuscation (renaming) on its own. Test startup and the previously failing operation after each change. If it works, enable another feature and repeat.
  4. Confirm the first failing change. Disable the last feature again and verify that the application works. Then test that feature on its own to determine whether the failure requires a combination of settings.

Keep a record of the settings and result for each test. The last feature enabled identifies a useful starting point for investigation. This does not necessarily mean that the feature fails in every configuration.

Initially leave merging, embedding, and bundling unchanged so that you do not change several variables at once. If the application still fails with protection options disabled, test these packaging settings separately. A simplified folder deployment can help, but it must include the dependencies that are no longer merged, embedded, or bundled.

If the original application works but a minimal .NET Reactor configuration still fails, preserve that reproducer and the logs for support. Do not assume that the issue must be in your application merely because no individual protection setting has been identified.

# Use Debug names to inspect renaming

For a separate inspection build, keep Obfuscation enabled and set Naming Convention → Debug. The original name remains recognizable with a Δ_ prefix, making it easier to identify which types and members were renamed.

Debug naming still changes names. It can therefore still trigger reflection or public-API compatibility problems. It is an inspection aid, not a replacement for disabling renaming when isolating the cause. Keep the public-type settings and exclusions unchanged while examining their effect, and do not distribute the Debug-named build.

# 4. Investigate common compatibility problems

# Renaming and reflection

If the application works with Obfuscation disabled but fails when it is enabled, investigate code and frameworks that locate types or members by their original names. This includes string-based reflection, plug-in discovery, configuration-driven activation, and UI bindings.

For example, code that looks up a method named Initialize may no longer find it after renaming. The relevant lookup may be inside a library or framework rather than in your own startup method.

Preserve the names required by these runtime contracts with targeted renaming exclusions, or change the code so that it no longer depends on those names. Do not leave all protection disabled when an exclusion for a specific type or member is sufficient.

See Reflection Problems, Declarative Protection, and Advanced Rules Editor. For WPF, also see WPF and XAML bindings.

# Public types renamed without their consumers

If Obfuscate Public Types is enabled, check whether all assemblies that reference the renamed types and members are included in the same protection run. Merely placing those files beside the main assembly does not configure them for coordinated protection.

Add the relevant application assemblies to Additional Assemblies and protect them together. Scan Main Assembly Dependencies is a useful starting point, but also account for plug-ins or other consumers that are not ordinary references of the main assembly.

For example, if MyLibrary.dll is protected with public-type renaming but its consuming MyApp.dll is not processed in the same run, the application can still reference names that no longer exist. Typical symptoms include type-loading or missing-method errors.

If a consumer cannot be included, preserve the public names it uses through appropriate exclusions or disable Obfuscate Public Types for the affected library. A library intended for independently built consumers needs a stable public contract.

See Public Type Obfuscation.

# Serialization during startup

Applications often deserialize configuration, cached objects, persisted state, or service responses during initialization. Renaming can affect serializers that depend on type or member names, even when startup code does not explicitly use reflection.

Test with the same data that triggers the failure. Include data created by earlier application versions where compatibility is required. A test with an empty cache or newly generated data can miss the problem.

Use targeted renaming exclusions or an explicitly stable serialization contract. .NET Reactor detects many common serialization patterns, but custom contracts and dynamically discovered members may need additional configuration.

See Serialization.

# Trimming and publishing order

Check whether trimming runs before or after protection. The required configuration is different for these two workflows.

When trimming runs before protection, add and configure Eziriz.Reactor.TrimHelper before publishing, then regenerate the input and protect it again. This is especially important when opening an already trimmed single-file application in .NET Reactor. Adding the helper after the trimmed bundle has already been created does not repair that bundle.

When trimming runs after protection, follow the protection-feature restrictions in Trimming Problems. Do not assume that adding TrimHelper makes every protection feature compatible with post-protection trimming.

As a diagnostic comparison, publish a separate build without trimming and protect it with the same settings. If that works, investigate the trimming configuration and warnings. The helper preserves requirements of Reactor's injected code. Application-specific reflection and serialization still need their own trimming-compatible configuration.

For pipelines that also use ReadyToRun, check the documented protection order in ReadyToRun.

# 5. Check runtime and environment-related causes

These checks are particularly useful when the failure occurs only on another computer, under another account, or after installation.

Symptom or condition What to check
A message says that .NET or a required framework is missing For a framework-dependent application, verify the runtime version, framework, and architecture named in the error. A Windows desktop application may require the Desktop Runtime rather than only the base runtime. See Microsoft's app-launch troubleshooting guide.
A self-contained application fails only after copying it Verify the complete runtime payload and native prerequisites for its target OS and architecture. Self-contained does not mean independent of all operating-system dependencies. See .NET publishing modes.
A DLL cannot be found or loaded Check managed and native dependencies, their versions, the published directory layout, and the process architecture. A native dependency can itself depend on another missing native library.
BadImageFormatException Check architecture and file-format mismatches, including native libraries and the actual file being loaded. The exception alone does not identify a particular protection feature. See Microsoft's exception reference.
Startup stops with an evaluation or licensing message Check your application's license-file location, hardware binding, and configured evaluation or expiration settings. This is separate from .NET Reactor activation. See How Locks Work.
The application works before another build step changes it Check whether a later tool rewrites the protected assembly. Anti Tampering performs runtime integrity checks. Follow the documented workflow for later transformations and signing rather than modifying protected files arbitrarily.
Files disappear, access is blocked, or a security product reports a detection Check quarantine and security-product logs. Investigate a possible Antivirus False Positive. Do not treat globally disabling antivirus as the solution.
The application starts from one location or account but not another Compare the working directory, relative file paths, environment variables, and access to configuration, data, and required writable locations. For bundles that extract files, also check access to the extraction location.

# 6. Verify the fix and prepare a support case if needed

After correcting the cause, restore the intended release settings and generate fresh protected output. Repeat the test against the final deployment or installed setup package, not just the diagnostic build.

Test more than startup: exercise the affected reflection paths, serialization, plug-in loading, UI initialization, and licensing behavior. Remove temporary diagnostics and Debug naming from the release configuration. See Verify Protected Output.

If the issue remains, prepare a small reproducible example for Technical Support. Include:

  • The .NET Reactor version, target framework, OS and architecture, and publishing options, including trimming, single-file publishing, and ReadyToRun.
  • The full error report and protection log, the exact input/output locations, and whether the failure occurs directly from Reactor output or only after packaging or installation.
  • The smallest configuration that fails, the nearest configuration that works, and confirmation that the corresponding unprotected application works in the same environment.

Review project files and command lines for master keys, certificate passwords, and other secrets before sharing them. Use the official support channel for private sample files.

# Related topics

Reflection Problems · Public Type Obfuscation · Serialization · Trimming Problems

Verify Protected Output · Single-File Publishing · Debugging Stack Traces

Publishing · Debugging