The error code 0x887a0006 means Windows lost contact with your graphics card's device object mid-frame, and the accompanying "badly formed commands" text is describing a driver-level fault escalation, not a syntax mistake in your code. The condition that matters: if you write DirectX code (or run software that does), the fix splits cleanly in two β€” for players, it's driver and power-delivery troubleshooting; for developers, it's adding device-removed handling and validating every command you submit to the GPU.

This is a stable, well-documented DirectX Graphics Infrastructure (DXGI) behavior. The message text itself comes from Microsoft's own debug output layers and is pasted verbatim into countless crash dialogs. Understanding what it actually signals β€” and who is responsible for fixing it β€” resolves most confusion about this error.

What 0x887a0006 Actually Reports

DXGI_ERROR_DEVICE_REMOVED is HRESULT 0x887A0006, a documented constant in Microsoft's DXGI error enumeration, and DXGI_ERROR_DEVICE_HUNG (0x887A0006) shares the same numeric value because a hung device is escalated to a removed device. The device object is the software handle your program holds on the GPU; "removed" means the operating system or driver revoked that handle, and every subsequent call on it fails. Nothing about your hardware is necessarily broken.

Microsoft's documentation defines device removal as the situation where the device no longer exists from the application's perspective. The trigger can be a driver update, a GPU reset from a timeout detection and recovery (TDR) event, a physical unplug of the display adapter, or a driver crash. When the driver's watchdog detects that a command has run past the timeout threshold β€” two seconds by default on most consumer Windows systems β€” it resets the GPU and tears down the device.

The message names two causes: bad commands and a hung device. These are different paths to the same result. Badly formed commands thrown at the GPU can cause the driver to fault; a hung device means commands stopped completing. Either way, DXGI reports removal rather than identifying which specific command was at fault, because the fault is raised after the driver has already reset.

One distinction matters. DXGI_ERROR_DEVICE_REMOVED is a recoverable state if your application is built to recreate its device and resources. It is fatal only to code that never checks for it. That is why you see the error so often from games and creative tools that don't implement recovery, and why the "design-time issue" phrase points at the application, not the user.

Badly Formed Commands: Why the Wording Blames the Application

The phrase "badly formed commands sent by the application" is diagnostic shorthand for invalid or malformed GPU command submissions, and it appears most often when running under a debug layer that can detect such faults. In Direct3D 12, an invalid resource state transition, a command list that references a destroyed resource, or a descriptor heap pointer that no longer matches will fault the driver. The driver cannot "return" that error to your code mid-submission, so it resets the device and DXGI reports removal.

In Direct3D 11, the equivalent class of mistakes includes binding a resource that's already in use elsewhere in a way the driver can't resolve, presenting with an invalid swap chain, or submitting work after the device was already lost. The API is more forgiving than D3D12, but it's not immune. If you enable the D3D11 or D3D12 debug layer, the debug output will typically name the offending call before the removal arrives.

The word "application" in the message is literal. Microsoft's own documentation on device removal says applications should not assume the device will remain available and must handle removal explicitly. If your program submits commands and never checks the return code of Present, ExecuteCommandLists, or Map, you are the application the message is describing. Users running someone else's software aren't doing anything wrong.

Here is where the message becomes genuinely useful: it rules out the GPU as the primary suspect. Badly formed commands point at submission code. Repeated removals without malformed submissions point at the driver, power, or hardware. Tell those two cases apart before you change a single setting.

The TDR Timeout: The Two-Second Rule Most Guides Get Wrong

Windows uses a watchdog called Timeout Detection and Recovery, and its factory timeout is 2 seconds (TdrDelay), set in the registry by the display driver model. If the GPU doesn't respond within that window, Windows resets it and the device is removed. This is the single biggest cause of 0x887a0006 that users hit without touching any code.

The timeout exists because a hung GPU would otherwise freeze the whole desktop indefinitely. A 2-second threshold is invisible in normal gameplay but tight for workloads that legitimately run single GPU commands longer than that. Heavy compute kernels, very large texture uploads, and some rendering pipelines can trip it inadvertently. When they do, the application receives device removal even though it did nothing malformed.

You can raise the threshold through the registry values TdrDelay (seconds before reset) and TdrDdiDelay, but Microsoft explicitly warns that extending the timeout only masks a real hang and is intended for debugging, not as a permanent fix. Changing those values also requires a reboot, and they apply system-wide, so any other application that genuinely hangs will now freeze your desktop for the longer window.

Diagnostic shortcut: if the error appears only under heavy rendering and only in a specific title, TDR is the likely mechanism. If it appears at the desktop with no GPU workload, suspect the driver or power. If it appears the instant you launch a specific program, suspect that program's submission code. Three different fixes follow from three different triggers.

Diagnosing Which Layer Failed

Before changing anything, establish where the failure originates. The evidence differs by layer, and picking the wrong remediation wastes days. Use Windows Event Viewer's System log and filter for "Display" source entries; a TDR event is recorded as "Display driver stopped responding and has recovered," which confirms the watchdog fired.

For developers, the Direct3D debug layer is the definitive tool. Enable it with D3D12GetDebugInterface and EnableDebugLayer() in D3D12, or the matching D3D11_CREATE_DEVICE_DEBUG flag in D3D11, then read the debug output. It will report specific invalid states, resource hazards, and descriptor errors in plain language before the device is ever lost. Microsoft's DirectX team treats debug-layer output as authoritative.

For end users, the process is subtractive. Test whether the error follows the application across different GPUs, whether it survives a clean driver install using Display Driver Uninstaller, and whether it correlates with power events like sleep or adapter switching. On laptops with hybrid graphics, removal frequently correlates with switching between the integrated and discrete GPU, which is an application-level handoff problem disguised as a hardware fault.

Track the recovery. If the application continues operating after the error, some component recreated the device. If it crashes, the application has no recovery path. That distinction tells you whether you're fixing a bug or patching around one.

Step-by-Step Fix for End Users

Work through these in order. Each step is cheap, and the order moves from most likely to least, so stop as soon as the error stops.

1: Update your GPU driver from the manufacturer's own tool β€” Nvidia App, AMD Software: Adrenalin Edition, or Intel Driver & Support Assistant β€” rather than Windows Update, which often ships older versions. 2: Perform a clean install: download the driver, run Display Driver Uninstaller in safe mode to strip leftovers, then install fresh. 3: Set Windows power plan to High Performance and, in the GPU control panel, set the application to "Prefer maximum performance" so the adapter doesn't downclock mid-frame. 4: Disable any overclock, including factory overclocks, and test again at stock settings. 5: Update the game or application itself. Many titles ship fixes for specific device-removal crashes in patch notes. 6: Check the display cable and connection if the error coincides with flicker or a monitor going black. 7: If all else fails, revert the TdrDelay registry value to its default after any experiment.

If the error persists after a clean driver install at stock clocks, the problem is almost certainly in the application's submission code, and no user-side setting will fix it. Report it to the developer with your GPU model, driver version, and the exact application version.

Failure handling matters. If a clean driver reinstall doesn't change the error frequency, stop reinstalling drivers β€” you're repeating a fix that has already been ruled out, and each cycle risks introducing a new variable. Move to the developer-side explanation instead.

Step-by-Step Fix for Developers: Handling Device Removal

Treat device removal as a normal operating condition, not an exception. This sequence matches how Microsoft's own samples structure recovery.

1: Check the HRESULT of every Present, ExecuteCommandLists, Map, and ResourceBarrier submission path β€” if it equals DXGI_ERROR_DEVICE_REMOVED, enter recovery instead of continuing. 2: Call GetDeviceRemovedReason() to distinguish DXGI_ERROR_DEVICE_HUNG, DXGI_ERROR_DEVICE_RESET, and DXGI_ERROR_DRIVER_INTERNAL_ERROR; the reason narrows where to look. 3: Tear down the swap chain, all device-created resources, descriptor heaps, command lists, and pipeline state objects before releasing the device itself. 4: Recreate the ID3D12Device or ID3D11Device, re-query capabilities, rebuild resources from your own CPU-side data, and recreate the swap chain with the current window size. 5: Enable the debug layer during development and validate resource states and descriptor bindings so malformed submissions are caught before the driver faults.

On the D3D12 side, the most common malformed-command cause is a resource state mismatch β€” a texture transitioned to D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE when the shader expects something else. The debug layer catches this, but only if it's enabled. Ship with it off; develop with it on.

Failure-handling close: recovery loops need a cap. If the device is removed three times in quick succession, exit gracefully rather than recreating forever, because an infinite recreate loop on a genuinely faulty GPU will thrash the driver and lock the machine. Log the GetDeviceRemovedReason() value on each attempt so support can see the pattern.

Comparing Removal Reasons and What Each Implies

The reason code returned by the API tells you more than the generic 0x887a0006 text ever will. The table below maps each documented reason to its likely cause.

Device removed reason Typical cause Who can fix it Recovery viable
DXGI_ERROR_DEVICE_HUNG Command exceeded TDR timeout; infinite loop in shader Developer (submission code) Sometimes, after fixing
DXGI_ERROR_DEVICE_RESET Driver detected fault and reset Developer or driver vendor Yes
DXGI_ERROR_DEVICE_REMOVED Adapter physically removed or driver unloaded User (hardware) or driver vendor No
DXGI_ERROR_DRIVER_INTERNAL_ERROR Driver bug or resource exhaustion Driver vendor Usually no

The verdict split: a hung device with a shader that loops forever is a code bug and recovery without a fix will recur. A reset from a driver-internal fault is the vendor's responsibility, and recovery is the right response. A physically removed adapter is not recoverable at all β€” recreate on the new adapter or exit. Read the reason before deciding which of the three you're in.

Malformed Command Patterns That Trigger Removal

The debug layer names these, but knowing the top offenders speeds up the search. In D3D12, a resource accessed while still in a write state from a prior frame is the most frequent culprit. The API doesn't enforce state correctness at runtime; it trusts you, and the driver faults when the command buffer is invalid. Similarly, a command list executed twice without a reset, or a descriptor heap that was reallocated while still referenced by in-flight work, will fault.

In D3D11, the equivalent traps are more subtle. Calling Present on a swap chain whose window has been resized to zero, or mapping a resource that's currently bound for rendering, can trigger the driver fault path. These are timing-sensitive, which is why malformed-command errors look intermittent: the same code can run cleanly for hours and then fault when a window message arrives at the wrong moment.

Synchronization errors sit in their own category. Submitting command lists that write to the same resource in the same frame without a barrier produces undefined ordering, and while it may not always trigger removal, it sometimes does. Debug-layer detection of resource hazards is worth the performance cost during development because it converts these silent faults into named lines in the output window.

The practical rule: any call that can fail should be checked, and any resource used across frames should have its state verified in code review. The message calls this a design-time issue because, from the driver's perspective, it is one.

When It's the Hardware or Platform, Not the Code

Not every removal is a software problem. Specific hardware and platform conditions reliably produce 0x887a0006 independent of any submission error. The most documented is PCIe link instability: if the card drops its link under load because of a riser cable, insufficient slot power, or an overclocked PCIe bus, the driver loses the device and Windows reports removal.

On laptops, the hybrid graphics handoff is a recurring source. Software that doesn't handle DXGI_ERROR_DEVICE_REMOVED when the discrete GPU powers down after the application stops using it will surface the error at the next frame. AMD's and Nvidia's documentation both note that adapter switching can produce removal events, and applications are expected to recover.

A second hardware case is the display adapter being reset by a driver update mid-session. If the driver package updates while an application is running, the device can be removed and the new driver's device isn't the one the application holds. Windows Update does this. Users notice the crash and blame the application.

Ruling hardware in or out is straightforward. If the error occurs in a title that is widely reported as stable on identical hardware with a current driver from a clean install, suspect the local platform β€” slot power, riser, thermal throttling, or the power supply. Isolate by testing the same software on a second machine before swapping parts.

FAQ

Does 0x887a0006 mean my graphics card is dying?

No β€” in most reported cases the card is healthy, and the error reflects a device object being revoked by a driver reset. Passing the error through a GPU stress test and a clean driver install at stock clocks is how you rule out hardware. If both run clean and the error only appears in one application, the card is not at fault.

Is "badly formed commands" a virus or malware message?

It's not a security warning. The text comes from Microsoft's DXGI debug output and is printed when the driver faults, not when malicious code runs. A malware scan is still worthwhile if you suspect tampering, but the phrasing itself has nothing to do with infections β€” it's DirectX diagnostic language that predates most modern threats.

Can I just raise the TdrDelay registry value to stop the crashes?

You can, but Microsoft documents the timeout extension as a debugging aid, not a permanent fix, and the default is 2 seconds for good reason. Raising it delays recovery from genuine hangs and freezes your desktop for the longer window. Only do it to identify whether the trigger is the watchdog, then revert.

Why does it crash in D3D12 but not in an older D3D11 game?

D3D12 hands the driver pre-validated command buffers and trusts the application to get state transitions right, so malformed submissions fault at the driver instead of returning a comfort error. D3D11 validates more at runtime. This is why 0x887a0006 concentrates in modern titles and tools.

Does a driver rollback help if a clean reinstall didn't?

Sometimes β€” a clean reinstall of the same version can't fix a regression in that version. Rolling back two or three releases, or testing the vendor's previous Studio/Game Ready branch, isolates whether the driver version is the trigger. If the error vanishes on rollback, report the regression to the vendor with both version numbers.

I'm a developer and my device recovers but the error floods the log β€” is that normal?

That's a recovery loop. Device removal should be rare; three or more removals in a short session indicates a persistent malformed submission or a platform fault, and capping recovery attempts is standard practice. Log GetDeviceRemovedReason() each time so the pattern becomes visible.

Does this error exist on consoles or other operating systems?

No β€” DXGI is part of Windows and its graphics stack, and the HRESULT constant is specific to that platform. Other operating systems use their own device-loss APIs with different codes. Cross-platform engines must translate it into their own abstraction rather than handling the Windows constant directly.

This article covers general technical and troubleshooting information about a documented Windows graphics API error and is not a hardware diagnosis or a warranty recommendation. Driver, registry, and card-level changes carry risk; consult the GPU maker's official support documentation, and for suspected hardware failure contact a qualified technician.