0X00000BC2

ERROR_SUCCESS_REBOOT_REQUIRED (0x00000BC2): Why a Successful Install Still Demands a Reboot

0x00000BC2 isn't a crash. It's Windows telling your installer the job is done but a reboot must happen before the changes take effect.

You're running an installer, a deployment script, or a Windows Update call, and instead of a clean zero you get 0x00000BC2. The name is the giveaway: ERROR_SUCCESS_REBOOT_REQUIRED. Nothing failed. Windows is telling you the operation finished but the changes are parked in a pending state until the machine restarts. People see the word "error" and start troubleshooting a problem that doesn't exist.

What's actually happening here is that the component you installed replaced files that were locked by a running process, or wrote registry keys that only load at boot. Windows stages the new versions, queues the swap for the next startup, and returns 0x00000BC2 so your automation knows to schedule that restart. An MSI returns the same condition as exit code 3010; an InitiateSystemShutdown call returns it as ERROR_SUCCESS_REBOOT_INITIATED (which is a different number, 0x0000045C, so don't confuse the two).

The real question isn't "how do I fix 0x00000BC2." It's "why did my process surface it when I expected a plain success." There are three reasons, and they stack in a specific order of likelihood.

Cause 1: An installer replaced a file that was in use (MSI return code 3010)

This is the one you'll hit nine times out of ten. You push a patch, a driver package, or a .NET runtime update while the target files are held open. Windows can't delete or overwrite a loaded DLL or a running service binary, so it renames the old one to a pending-rename entry and defers the actual replacement to the next boot. The install itself returns success. The reboot flag is the receipt.

A concrete trigger: you're rolling out a Visual C++ redistributable to a fleet of Windows 10 22H2 machines, and msiexec /i vc_redist.x64.exe /quiet /norestart runs while explorer.exe and a handful of apps have the old CRT DLLs mapped. You get 3010 back on every box that had those DLLs loaded. Machines that were fresh or idle return 0. Same package, different result, purely because of what was running.

For a single machine, just reboot. That's the whole fix. For automation, you need to treat 3010 as success-with-a-caveat rather than a failure:

msiexec /i "package.msi" /quiet /norestart
if %ERRORLEVEL%==3010 (
    echo Install succeeded, reboot pending
    shutdown /r /t 60 /c "Reboot required by package install" /d p:4:1
) else if %ERRORLEVEL%==0 (
    echo Install complete, no reboot needed
) else (
    echo Real failure: %ERRORLEVEL%
    exit /b %ERRORLEVEL%
)

In PowerShell, the pattern is the same but cleaner:

$p = Start-Process msiexec.exe -ArgumentList '/i','package.msi','/quiet','/norestart' -Wait -PassThru
switch ($p.ExitCode) {
    0     { 'Success' }
    3010  { 'Success, reboot required' }
    1641  { 'Success, reboot already initiated' }
    default { throw "Install failed: $($p.ExitCode)" }
}

Note the second code, 1641 (ERROR_SUCCESS_REBOOT_INITIATED). If your package used /forcerestart or the MSI had REBOOT=Force set, you'll see that instead. It also means success. Don't ignore it.

Cause 2: A pending reboot was already queued before your process ran

Sometimes your installer didn't do anything wrong. Windows was already sitting on a pending operation from an earlier Windows Update, a driver install, or a failed uninstall that left a tombstone behind. Your call just surfaced the existing state.

The reason this matters: if you're sequencing installs, a stale pending reboot can make the second install return 3010 even though the second package needed no restart of its own. You end up rebooting for no reason, or worse, your orchestration tool marks the step as incomplete.

Check for pending reboots before you start. Four registry locations give the game away:

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending
  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired
  • HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations
  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending

Any one of those keys existing means a reboot is already owed. PowerShell one-liner to check all of them:

function Test-PendingReboot {
    $paths = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending',
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired',
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending'
    )
    foreach ($p in $paths) { if (Test-Path $p) { return $true } }
    $pfro = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name PendingFileRenameOperations -ErrorAction SilentlyContinue)
    if ($pfro.PendingFileRenameOperations) { return $true }
    return $false
}

Wire that into your deploy script's preamble. If it returns $true, reboot first, then run your install. You'll get an honest answer instead of a 3010 that belongs to somebody else's unfinished business.

Cause 3: You're catching the code and treating it as an exception

This one is a logic bug in your own code, not a Windows condition. A lot of installer wrappers do a blanket "if return code != 0, throw" check. 0x00000BC2 isn't zero, so it throws, your CI pipeline goes red, and someone spends an afternoon chasing a phantom.

The fix is to widen your success set. Any return code in the 0x00000BC2, 3010, or 1641 family is fine — it just means "done, restart later." Here's the shape of the check you want, in C#:

const int ERROR_SUCCESS = 0;
const int ERROR_SUCCESS_REBOOT_REQUIRED = 0x00000BC2; // 3010
const int ERROR_SUCCESS_REBOOT_INITIATED = 0x0000045C; // 1641

bool Succeeded(int code) =>
    code == ERROR_SUCCESS ||
    code == ERROR_SUCCESS_REBOOT_REQUIRED ||
    code == ERROR_SUCCESS_REBOOT_INITIATED;

If your wrapper logs exit codes to a monitoring system, tag 0x00000BC2 as a warning, not an error. That way the reboot demand is visible without paging anyone at 3 a.m.

One thing to be careful about: don't call InitiateSystemShutdown with the abort flag and then immediately re-issue, expecting a different result. If a reboot is already pending, Windows keeps returning the reboot-required code until the machine actually restarts. Retrying the operation just re-stages the same pending changes.

When it's not actually benign

Two edge cases are worth knowing. First, if you see 0x00000BC2 repeatedly from a scheduled task on the same machine and the machine never reboots, the pending operation never completes, and the next run stacks another one on top. You can end up with a PendingFileRenameOperations entry list hundreds deep. That's a real problem and the symptom is a machine that hangs at boot. If you find that, clear the stale entries manually or run the System File Checker, then reboot cleanly.

Second, if the value appears during a Windows Update scan and the reboot never clears the flag, check for a stuck service — usually TrustedInstaller or wuauserv refusing to release a lock. Restart those services manually and try the update again.

Quick reference

CauseHow to confirmFix
Installer replaced a locked fileMSI exit code 3010 or 1641Reboot. Treat 3010 as success in scripts.
Stale pending reboot from earlier workCheck RebootPending, RebootRequired, PendingFileRenameOperations keysReboot before starting the new install.
Code treats non-zero as failurePipeline fails on 0x00000BC2 but install logs show successWhitelist 0x00000BC2, 3010, 1641 as success states.
Reboot flag never clearsRepeated 0x00000BC2 across days, machine won't restart cleanlyClear stale PendingFileRenameOperations, SFC, restart TrustedInstaller/wuauserv, reboot.

Bottom line: 0x00000BC2 is Windows being polite. It's saying "I did what you asked, now restart me." Don't debug it. Don't suppress it. Just schedule the reboot and move on.

Related Errors in Windows Errors
0X00003ABC Fixing 0x3ABC: Event Log Channel Won't Open 0X000005B4 Fix ERROR_TIMEOUT 0X000005B4 – Timeout on Windows 0X00000778 OR_INVALID_SET (0X00000778) Fix: Object Set Not Found 0X80290208 Fix TBSIMP_E_INVALID_PARAMETER (0x80290208) in 5 Minutes

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.