You'll see 0x000005B3 the moment a process that isn't attached to your desktop tries to draw something. A Windows service calling MessageBox. A scheduled task running as SYSTEM trying to launch an installer with a UI. An OpenSSH session on Windows Server 2022 where you type notepad.exe and get back This operation requires an interactive window station. Or a CI agent — Jenkins, GitLab Runner, Azure Pipelines self-hosted agent — running under a service account and firing off a tool that pops a consent dialog. The call that fails is usually one of CreateWindowEx, MessageBox, or ShowWindow, and the process is sitting in a window station that has no visible desktop.
What's actually happening here
Windows doesn't have one desktop. It has window stations, and each window station owns one or more desktops. Your logged-in session gets WinSta0 — the only window station in the system that's flagged WSF_VISIBLE and wired to the physical display, keyboard, and mouse. Every other window station (Service-0x0-3e7$ for SYSTEM services, Service-0x0-<LUID>$ for service accounts, the anonymous logon station) is headless. It exists so processes have a place to put their objects, not so anyone can see them.
When your code tries to create a window, the window manager walks up from the current thread's desktop to its window station and checks the interactive flag. No flag? The API fails with STATUS_REQUIRES_INTERACTIVE_WINDOWSTATION, which surfaces to Win32 as error 1459 (0x5B3). This isn't a permissions problem in the usual sense — even an administrator token can't draw on a non-interactive station. It's structural.
Blame Session 0 Isolation, shipped in Windows Vista and still very much alive in Windows 11 23H2 and Server 2025. Before Vista, the first service to log on shared Session 0 with the first interactive user, so a service could sneak a dialog onto the user's desktop. That was also how shatter attacks worked. Microsoft split them, and services have been cut off from the visible desktop ever since.
The fix
Pick the option that matches why your process is running headless. Don't mix them.
-
If it's a scheduled task: open Task Scheduler, select the task, go to the General tab, and tick Run only when user is logged on. Then under Properties → Settings, make sure Hidden is unchecked. What this does is run the task in the user's own session and window station instead of the service session. The tradeoff is real: the task won't fire if nobody's logged in. If you need it to run whether or not the user is present and show UI, you can't — those two requirements are mutually exclusive by design.
-
If it's your own service that needs to prompt a user: stop calling MessageBox from the service. Use
WTSSendMessagewith the target session ID (fromWTSEnumerateSessions) to push a message box into the user's session. Or use theCreateProcessAsUserroute with the token of a logged-on user. For quick debugging, ServiceUI.exe from the MDT toolkit does the heavy lifting:ServiceUI.exe -process:MyService.exe notepad.exeThat spawns notepad in the interactive session tied to the service. It's a debugging toy, not a shipping pattern.
-
If it's PsExec: you forgot the
-iflag.psexec \\host -s cmd.exeruns in Session 0 with no desktop. Add-i(optionally with a session number) and the process lands on the interactive station:psexec \\HOST -i -s cmd.exeNote that for
-ito help, someone has to actually be logged on at that machine. On a headless server with no RDP session,-idoes nothing useful. -
If it's OpenSSH on Windows: the default sshd runs as a service, so GUI apps launched over SSH can't display. Your options are to use SSH only for command-line tools (fine for most automation), or to launch GUI tools through a helper like
schtasks /create /tn gui /tr "C:\path\app.exe" /sc once /st 00:00 /itwhere/itmeans interactive-only. Then trigger it withschtasks /run /tn guifrom the SSH session. Clunky, but it works. -
If it's your own code: the honest fix is to remove the UI dependency. Replace MessageBox with
EventLog.WriteEntryor a log file, replace modal dialogs with headless callbacks. If the app absolutely must show UI, split it: a headless service does the work and writes results, and a small interactive client (launched at user logon via Run key or Startup folder) reads them. That's the pattern every well-behaved Windows agent uses — antivirus, backup tools, update clients.
If it still fails
Check which session the process is actually in. Open Task Manager, go to the Details tab, right-click the column header and enable Session ID. Anything in session 0 is headless. Anything in session 1+ belongs to a logged-on user and can draw.
Confirm the window station with Process Explorer: select the process, View → Lower Pane → Handles, filter for WindowStation. You'll see WinSta0 for interactive processes and Service-0x0-* for the others.
Also sanity-check the user profile. A broken or unloaded profile can prevent session creation entirely, and you'll see 0x5B3 alongside 0x80070005 in the event log. Try logging in interactively as that user once — if the profile rebuilds successfully, the scheduled task or service run under that account may start working.
And if the process is a service that used to work on Server 2008 or 2003, that's your answer: Session 0 Isolation arrived and nobody updated the code. The error isn't a bug you disable — it's Windows enforcing a boundary that predates your code. Rewrite the UI path or accept that it runs headless.