# How to Troubleshoot .NET MAUI Application Issues and Environment Setup

> Troubleshoot .NET MAUI application issues and environment setup with the dotnet skills repository. Validate workstations, configure workloads, and diagnose crashes easily.

- Repository: [.NET Platform/skills](https://github.com/dotnet/skills)
- Tags: how-to-guide
- Published: 2026-07-07

---

**The dotnet/skills repository provides automated diagnostic skills that validate MAUI development workstations, configure .NET workloads, and diagnose runtime crashes through a unified skill-validator framework.**

The dotnet/skills repository contains a collection of self-contained skills that automate common .NET development tasks. For .NET MAUI developers, the most relevant tools live under `plugins/dotnet-maui/skills/`, where automated diagnostics encode the full knowledge needed to troubleshoot .NET MAUI application issues and validate environment setup across Windows, macOS, Linux, Android, and iOS targets.

## Understanding the MAUI Diagnostic Architecture

The diagnostic system in dotnet/skills operates through a layered architecture defined in [`eng/skill-validator/src/Program.cs`](https://github.com/dotnet/skills/blob/main/eng/skill-validator/src/Program.cs). The **Skill Dispatcher** loads each skill's markup from [`SKILL.md`](https://github.com/dotnet/skills/blob/main/SKILL.md) files and executes validation tasks automatically.

The **MAUI Doctor** skill, located at [`plugins/dotnet-maui/skills/dotnet-maui-doctor/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/dotnet-maui-doctor/SKILL.md), serves as the primary entry point for environment validation. It detects missing workloads, incorrect JDK versions, and improper Windows SDK installations by querying the NuGet API for exact workload versions required by your project.

## Validating Your Development Environment

Before building MAUI applications, you must verify that platform-specific prerequisites are met. The skill references in [`plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-windows.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-windows.md) define the exact requirements for Microsoft OpenJDK, Xcode, and Windows SDK installations.

To run the automated environment check:

```bash
dotnet skill-validator run dotnet-maui-doctor

```

This command executes the validation logic defined in the MAUI Doctor skill, which checks for the presence of `maui`, `maui-android`, `maui-ios`, and other platform-specific workloads.

## Installing and Verifying .NET MAUI Workloads

When the doctor identifies missing components, install the required workloads using the exact commands specified in [`plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/installation-commands.md):

```bash
dotnet workload install maui
dotnet workload install maui-android
dotnet workload install maui-ios

```

After installation, verify your configuration matches the project's target frameworks by comparing `dotnet workload list` output against the `<TargetFramework>` values in your project file, such as `net8.0-android` or `net8.0-ios`.

## Diagnosing Runtime Crashes and Native Errors

For production crashes, the **Diagnostic Skills** in [`plugins/dotnet-diag/skills/android-tombstone-symbolication/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-diag/skills/android-tombstone-symbolication/SKILL.md) symbolicate Android tombstones and iOS crash logs. This process pulls debug symbols from Microsoft's symbol server to translate native stack frames back to .NET source locations.

To symbolicate an Android crash:

```bash
dotnet skill-validator run android-tombstone-symbolication --tombstone path/to/tombstone.txt

```

## Resolving Common Development Issues

### Dependency Injection Configuration

The [`plugins/dotnet-maui/skills/maui-dependency-injection/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/maui-dependency-injection/SKILL.md) file warns against using `AddScoped` in MAUI applications. Because MAUI's DI container is built once in `MauiProgram.CreateMauiApp()`, scoped services behave like singletons unless you manually manage scopes.

Correct registration pattern:

```csharp
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); });

    // Use AddTransient or AddSingleton
    builder.Services.AddTransient<IMyService, MyService>();
    // Avoid: builder.Services.AddScoped<IMyService, MyService>();

    return builder.Build();
}

```

### Application Lifecycle Management

The [`plugins/dotnet-maui/skills/maui-app-lifecycle/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/maui-app-lifecycle/SKILL.md) defines the correct `Window` lifecycle events including `OnActivated` and `OnResumed`. It also documents the recommended Shell-based navigation pattern for handling app states across platforms.

### Theming and Resource Dictionaries

According to [`plugins/dotnet-maui/skills/maui-theming/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/maui-theming/SKILL.md), implement light/dark mode using `ResourceDictionary.ThemeDictionaries` rather than CSS themes, which cannot be switched at runtime.

```xml
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                <Color x:Key="PrimaryColor">#0078D4</Color>
            </ResourceDictionary>
            <ResourceDictionary x:Key="Dark">
                <Color x:Key="PrimaryColor">#0A84FF</Color>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Application.Resources>

```

## Summary

- The **MAUI Doctor** skill at [`plugins/dotnet-maui/skills/dotnet-maui-doctor/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/dotnet-maui-doctor/SKILL.md) automates environment validation by checking workloads, JDK versions, and SDK installations.
- Use `dotnet skill-validator run dotnet-maui-doctor` to execute the full diagnostic suite against your workstation.
- Install missing workloads with `dotnet workload install maui` and platform-specific variants like `maui-android` and `maui-ios`.
- Avoid `AddScoped` in `MauiProgram.CreateMauiApp()` because the DI container is built once at startup, making scoped services behave as singletons.
- Symbolicate native crashes using the **android-tombstone-symbolication** skill to debug production issues with proper symbol resolution.
- Implement theming through `ResourceDictionary.ThemeDictionaries` rather than CSS to support runtime theme switching.

## Frequently Asked Questions

### Why does the MAUI Doctor report JAVA_HOME errors even when Java is installed?

The MAUI Doctor validates that you are using the **Microsoft OpenJDK** distribution rather than other JDK implementations. According to [`plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-windows.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/dotnet-maui-doctor/references/platform-requirements-windows.md), the doctor checks for specific registry keys and path configurations. If `JAVA_HOME` points to a non-Microsoft JDK or is explicitly set when it should be auto-detected, the skill recommends unsetting the variable to allow the build system to use the Microsoft distribution installed with Visual Studio or the .NET SDK.

### How do I verify which MAUI workloads are installed on my machine?

Run `dotnet workload list` in your terminal to see installed workloads. The MAUI Doctor skill compares this output against the target frameworks specified in your project file's `<TargetFramework>` elements, such as `net8.0-android` or `net8.0-ios`. If the required workload versions do not match the NuGet API requirements for your project, the doctor suggests the exact `dotnet workload install` commands needed to synchronize your environment.

### What is the correct way to handle dependency injection in .NET MAUI?

Register services in `MauiProgram.CreateMauiApp()` using `AddTransient` or `AddSingleton` rather than `AddScoped`. As documented in [`plugins/dotnet-maui/skills/maui-dependency-injection/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-maui/skills/maui-dependency-injection/SKILL.md), the DI container is built once during application startup, meaning scoped services will not behave as expected unless you manually create and manage scopes. Use `AddTransient` for services that should be created per-dependency, and `AddSingleton` for services that should persist throughout the application lifetime.

### How do I debug native crashes in my MAUI Android application?

Use the **android-tombstone-symbolication** skill located at [`plugins/dotnet-diag/skills/android-tombstone-symbolication/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-diag/skills/android-tombstone-symbolication/SKILL.md). This tool retrieves debug symbols from Microsoft's symbol server to translate native Android tombstones into readable .NET stack traces. Execute the skill with `dotnet skill-validator run android-tombstone-symbolication --tombstone path/to/tombstone.txt` to identify the exact source location causing native crashes in production builds.