Windows sandbox (unelevated): CreateProcessAsUserW denial rendered as "-1073283067 (Win32 error -1073283067)" instead of the decoded error

Open 💬 0 comments Opened Jul 29, 2026 by kyle-sexton

Summary

On 0.146.0 the unelevated Windows sandbox backend renders a denied CreateProcessAsUserW
as:

CreateProcessAsUserW failed: -1073283067 (Win32 error -1073283067)

The elevated backend, on the same machine at the same version, renders the same denial
with the code decoded — so this is a per-backend rendering difference, not a version regression.

This is a reporting defect only — I am not reporting the underlying sandbox failure here.
That is already covered by #35871 (MSIX/Store pwsh cannot be launched under the restricted
token) and #32655 (helper resolution). This issue is strictly about the error string.

Two things are wrong with it:

  1. It is not a Win32 error code. -1073283067 is 0xC0070005 — facility 0x007

(FACILITY_WIN32), low 16 bits 0x0005, i.e. a wrapped ERROR_ACCESS_DENIED (5), not a Win32
error number. Labelling it (Win32 error -1073283067) sends readers looking up a code that
does not exist. Note it is not the canonical HRESULT_FROM_WIN32(5) = 0x80070005 either:
bit 30 is also set, giving the 0xC… form, which suggests the wrap site ORs 0xC0000000
rather than 0x80000000.

  1. The human-readable message is dropped. Access is denied. is the part that tells a user

this is a permissions problem. Without it the message is undiagnosable, and searching the
number finds nothing.

The value is also printed as a signed 32-bit integer, so it does not match the 0xC0070005 form
anyone would search for.

What version of Codex CLI is running?

codex-cli 0.146.0

What subscription do you have?

ChatGPT auth (auth mode: chatgpt). Plan tier not disclosed.

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64 (Windows 11 Pro 10.0.26200)

What terminal emulator and version are you using (if applicable)?

Windows Terminal. No multiplexer.

Codex doctor report

Not pasted in full — it includes local paths, MCP server inventory, and a thread/rollout
inventory. The two relevant facts, from their respective sources: codex doctor reports
sandbox restricted fs + restricted network · approval OnRequest, and ~/.codex/config.toml
sets [windows] sandbox = "elevated". Happy to supply the full codex doctor --json privately
if useful.

What issue are you seeing?

Payload below is line-wrapped for readability; the real string is one line prefixed
ERROR codex_core::exec: exec error:. Username redacted, -Command body elided.

windows sandbox: CreateProcessAsUserW failed: -1073283067 (Win32 error -1073283067)
| cwd=C:\Users\<user>\AppData\Local\Temp\codex-probe-146
| cmd="C:\Program Files\WindowsApps\Microsoft.PowerShell_7.6.4.0_x64__8wekyb3d8bbwe\pwsh.exe" -Command "..."
| env_u16_len=9094 | si_flags=256 | creation_flags=525312

I controlled for version by reproducing both forms on one machine at 0.146.0, against the same
MSIX pwsh target, varying only windows.sandbox:

| windows.sandbox | rendering of the same denial |
|---|---|
| elevated | CreateProcessAsUserW failed: 5 (Access is denied.), prefixed runner failed during SpawnChild: and suffixed (Windows error 5) |
| unelevated | CreateProcessAsUserW failed: -1073283067 (Win32 error -1073283067), no prefix, no suffix |

The two also differ beyond the label — elevated adds -NoProfile to the child command line —
so they look like distinct paths, only one of which decodes.

The same decoded form appears in #35871 (0.144.3, elevated, different reporter), which is
consistent with the decoding path being the older, correct one.

What steps can reproduce the bug?

Any run on the unelevated backend that reaches CreateProcessAsUserW and is denied shows
it. The elevated backend does not — it decodes the same denial. The route I hit it by:

  1. Windows 11, Codex CLI 0.146.0, ~/.codex/config.toml containing [windows] sandbox = "elevated".
  2. Leave C:\Program Files\WindowsApps\... on PATH so pwsh resolves to the Store build — this

supplies a denial (see #35871).

  1. Run a command that reaches the sandbox runner. The -c override is load-bearing: unelevated

is the backend that renders the bad string.

``
codex exec -s read-only -c 'windows.sandbox="unelevated"' --skip-git-repo-check "read ./somefile.txt and print line 1"
``

  1. Observe CreateProcessAsUserW failed: -1073283067 (Win32 error -1073283067).

Removing the WindowsApps entries from PATH makes the same command succeed. (#35871's author
reports MSIX + unelevated not failing for them, so the exact precondition may differ from
theirs — but the rendering defect is independent of whatever produced the denial.)

What is the expected behavior?

Render it the way the elevated backend already renders the identical denial at this same
version — decoded, with the system message preserved:

CreateProcessAsUserW failed: 5 (Access is denied.)

If the raw wrapped value is worth keeping for diagnostics, unsigned hex alongside the decoded
error would be strictly better than the current string:

CreateProcessAsUserW failed: 5 (Access is denied.) [0xC0070005]

Suggested handling: when the returned value carries facility FACILITY_WIN32, mask to the low 16
bits and format that as the Win32 error before looking up the message; fall back to the raw
value only when the facility is something else. And avoid labelling a non-Win32 value
"Win32 error".

Additional information

Related, deliberately not duplicated here:

  • #35871 — the MSIX/Store pwsh denial that produces this error on the sandbox path. It also

asks for a clearer message, but that ask is about naming the shell as the cause. This issue
is narrower and orthogonal: the numeric label is factually wrong and the system message is
dropped, whichever condition triggered the denial.

  • #32655 — helper (codex-windows-sandbox-setup.exe) resolved relative to the PATH shim rather

than the package release directory; blocks elevated mode independently.

View original on GitHub ↗