Return codes and install behavior in Intune

Overview

Every Win32 app you deploy with Intune ends its install command by returning a numeric exit code. Return codes are the contract between that installer and Intune: they tell the Intune Management Extension (IME) whether the install succeeded, failed, needs a retry, or requires a reboot. Get the mapping right and the Company Portal status, automatic retries, and reboot prompts all behave the way you expect. Get it wrong and a working app reports as failed, or a broken install quietly reports as success.

This guide explains what each return-code type means, the default codes Intune seeds for you, how the IME evaluates the codes after the install command exits, and where return codes fit alongside requirement rules, detection rules, and install behavior. You will also see how to capture an installer’s real exit code during testing so you only ever map codes you have verified.

What are return codes and how does Intune use them?

A return code (exit code) is the integer a process hands back to its caller when it finishes. After the IME runs your install command for a Win32 app, it reads that process exit code and matches it against the Return codes list defined on the app’s Program tab. The matched entry’s Code type determines what Intune does next: report success, mark the install failed, schedule a retry, or signal that a reboot is required.

Two points trip people up. First, the return code is only the installer’s self-report. Intune still runs your detection rules afterward to confirm the app is actually present, so a “Success” code with a failing detection rule still shows as not installed. Second, the codes are tied to the exact command Intune runs, so they must reflect whatever your install and uninstall commands actually launch, not the underlying installer you ran by hand.

The five return-code types

Intune maps every code to one of five types. Any exit code that is not present in the list is treated as Failed.

Code typeWhat Intune doesPractical note
SuccessMarks the install successful, then runs detection to confirm.Use for 0 and any vendor-specific success value you have verified.
FailedMarks the install failed and surfaces the error in reporting.The default for any unmapped code. Map a code here only when it truly means failure.
RetryRetries the install up to three times, waiting about five minutes between attempts.Best for transient conditions such as another installer already running.
Soft rebootCounts as success; a restart is recommended to finish.The classic 3010 “reboot required” code from MSI-based installers.
Hard rebootThe device must restart before further Win32 app processing.Other queued Win32 apps wait until the device has rebooted.

What are the default return codes in Intune?

When you create a Win32 app, Intune pre-seeds the Return codes list with the values that cover the vast majority of MSI and well-behaved EXE installers. For common apps you rarely need to touch them.

Program — Return codes

Specify return codes used to indicate post-installation behavior.

0Success
1707Success
3010Soft reboot
1641Hard reboot
1618Retry

Codes not listed here are treated as Failed.

These defaults map to standard Windows Installer semantics: 0 is clean success, 1707 is also success, 3010 means the install worked but a reboot is needed (soft reboot), 1641 means the installer itself is initiating a restart (hard reboot), and 1618 means another installation is already in progress, so a retry is appropriate.

How the exit code becomes an install status

Walking the pipeline end to end makes it clear where return codes sit. Requirement rules are checked first, then detection runs to see whether the app is already present; only if it is missing does the install command run and produce the exit code that the return-code mapping interprets.

  1. Requirements passOS, architecture, and any custom rules are satisfied before anything runs.
  2. Install command runsThe MSI, EXE, .cmd, or PowerShell wrapper exits with a numeric code.
  3. Return code is mappedIME matches the code to Success, Failed, Retry, Soft reboot, or Hard reboot.
  4. Detection confirmsFor Success codes, detection rules verify the app is really installed.
  5. Status reportsResult is written to the IME logs and surfaced in the portal and admin center.

Because the IME drives this on the device, return-code outcomes are written to its logs in C:\ProgramData\Microsoft\IntuneManagementExtension\Logs (chiefly AppWorkload.log and IntuneManagementExtension.log), best read with CMTrace. If a result does not match what you see on the device, the IME logs show the exact code that was returned and how it was classified.

How does install behavior relate to return codes?

Return codes share the Program tab with the Install behavior setting, which selects the security context the install command runs in:

  • System context runs the install as the local SYSTEM account. It is device-wide and the common default for machine-level installers (per-machine MSIs, most EXEs).
  • User context runs as the signed-in user. The user must be logged on, and it suits per-user installers that write to the user profile or HKCU.

Context matters for return codes because the same installer can return different codes depending on permissions. A per-user installer forced to run as SYSTEM may exit with an access or “no user” error that you would otherwise never see. Pick the context that matches how the vendor expects the installer to run, then verify the exit code in that context.

How do I find an installer’s real return code?

Never map a code you have not observed. Run the exact install command on a clean test device in the same context Intune will use, then read the exit code. From an elevated PowerShell prompt, run the installer with -Wait -PassThru and read the returned process object’s .ExitCode property after it completes:

Start-Process -FilePath "setup.exe" -ArgumentList "/quiet" -Wait -PassThru | ForEach-Object { "Exit code: $($_.ExitCode)" }

For a PowerShell-script installer, make sure the script itself returns a deliberate code with exit 0 on success and a non-zero exit on failure, otherwise Intune may see the host process’s code rather than your intent. Record every code the installer can produce, then add only the meaningful ones to the Return codes list.

Common return-code mistakes

  • Mapping a failure to Success. Forcing a known-bad code to Success hides real breakage; the app reports installed while it is not, and detection or users surface the problem later.
  • EXE wrappers swallowing the real code. A bootstrapper or batch file that launches the true installer often returns its own exit code, not the installer’s. Wait on the child process and propagate its code.
  • Ignoring 3010. Leaving 3010 unmapped turns a normal “reboot required” into a Failed result. Keep it as Soft reboot.
  • Overusing Retry. Mapping a persistent failure to Retry just delays the failure across three quick retry attempts instead of reporting it promptly.
  • Confusing return codes with detection. A correct Success code still needs accurate detection rules for the app to show as installed.

When a return code signals a reboot, how Intune surfaces that to the user is governed by the Device restart behavior setting; see restart behavior and exit codes for the prompt, grace period, and forced-restart options. If status still looks wrong after you have verified codes, work through the Win32 troubleshooting checklist.

Quick checklist

  • Run the exact install command on a clean test device and record every exit code it can produce.
  • Keep the seeded defaults (0, 1707 Success; 3010 Soft reboot; 1641 Hard reboot; 1618 Retry) unless testing proves otherwise.
  • Add vendor-specific success codes only after you have observed them, and never map a real failure to Success.
  • Match Install behavior (System vs User) to how the installer expects to run before locking in codes.
  • Confirm detection rules pass for Success codes so the app reports installed.
  • If status disagrees with the device, read AppWorkload.log in the IME Logs folder with CMTrace to see the actual code.

Leave a feedback

Include versions, steps, and any error text if you have them.