Windows sandbox initialization fails with "setup refresh failed with status exit code: 1"

Open 💬 3 comments Opened May 25, 2026 by jiabirc6
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Bug Description
Codex desktop app on Windows fails to initialize the sandbox component, causing intermittent command execution failures. The error message is:

windows sandbox: setup refresh failed with status exit code: 1
Steps to Reproduce

Open Codex desktop app on Windows
Try to execute any shell command or use the js_repl tool
Observe that commands fail with the sandbox initialization error
Occasionally commands succeed, but failure rate is very high (~80-90%)
Expected Behavior
Shell commands and js_repl should execute reliably without sandbox initialization failures.

Actual Behavior

Shell commands fail with: Io(Custom { kind: Other, error: "windows sandbox: setup refresh failed with status exit code: 1" })
js_repl fails with: node_repl kernel exited unexpectedly ... windows sandbox failed: setup refresh failed with status exit code: 1
The error is intermittent - sometimes commands succeed, but most fail
Environment

OS: Windows (Chinese edition)
Codex Desktop App (latest version)
Node.js installed at: D:\nodejs
npm global prefix: D:\npm-global
Workspace: D:\codex
Config File (D:\codex-config\config.toml)

[sandbox]
mode = "danger-full-access"
sandbox.log Content

failed: SetNamedSecurityInfoW sandbox dir failed: 5
[2026-05-25 14:13:15.845 codex-windows-sandbox-setup.exe] setup error: helper_sandbox_lock_failed: lock sandbox bin dir C:\Users\Administrator\.codex\.sandbox-bin failed: SetNamedSecurityInfoW sandbox dir failed: 5
[2026-05-25 14:13:15.854 codex.exe] setup refresh: exited with status ExitStatus(ExitStatus(1))
Additional Context

Error code 5 in SetNamedSecurityInfoW is ERROR_ACCESS_DENIED
Setting mode = "danger-full-access" in config.toml does not resolve the issue
The sandbox setup binary (codex-windows-sandbox-setup.exe) appears to have permission issues accessing C:\Users\Administrator\.codex\.sandbox-bin
This makes the Codex desktop app nearly unusable on Windows as most operations require shell execution
Suggested Investigation

Check if codex-windows-sandbox-setup.exe has proper permissions to modify sandbox directories
Investigate why SetNamedSecurityInfoW fails with access denied
Consider providing a way to completely bypass sandbox setup on Windows
The danger-full-access mode should ideally skip sandbox initialization entirely

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 3 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #23587
  • #24101

Powered by Codex Action

jshaofa-ui · 3 months ago

Proposed Solution

Solution: Codex #24416 — Windows Sandbox Init Fails with SetNamedSecurityInfoW ERROR_ACCESS_DENIED

Issue: openai/codex #24416
Title: Windows sandbox initialization fails with "setup refresh failed with status exit code: 1"
Severity: High (~80-90% command failure rate on affected Windows systems)
Price Tier: $2,000–$3,000

---

1. Root Cause Analysis

1.1 Symptom Chain

User runs command → Codex CLI calls run_setup_refresh() → spawns codex-windows-sandbox-setup.exe
→ setup binary calls lock_sandbox_dir(sandbox_bin_dir) → SetNamedSecurityInfoW() → ERROR 5 (ACCESS_DENIED)
→ lock_sandbox_dir returns Err → mapped to HelperSandboxLockFailed → setup exits non-zero
→ orchestrator sees non-zero exit → "setup refresh failed with status exit code: 1"

1.2 Primary Failure Point: lock_sandbox_dir() in win.rs

File: codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs, lines 290–385

The lock_sandbox_dir() function constructs a new DACL with SetEntriesInAclW() and then calls
SetNamedSecurityInfoW() to apply it to the sandbox directory. On certain Windows configurations,
this call returns error code 5 (ERROR_ACCESS_DENIED).

Why SetNamedSecurityInfoW fails with ERROR_ACCESS_DENIED (code 5):

  1. UAC Token Filtering on Built-in Administrator: On Windows, when the built-in

Administrator account (or a member of the Administrators group) runs without an elevated
token, the process receives a filtered token that lacks the SE_RESTORE_NAME and
SE_TAKE_OWNERSHIP_NAME privileges. SetNamedSecurityInfoW requires SE_RESTORE_NAME when
setting a DACL that differs from what the caller's token naturally allows.

  1. Inherited Protected ACLs: The .sandbox-bin directory may be created under a parent

directory (e.g., C:\Users\Administrator\.codex) that has protected/inherited ACLs that
prevent even Administrators from freely modifying the DACL. Windows' ACL inheritance model
means the directory inherits deny ACEs or restricted ACEs from the parent.

  1. Windows Sandbox / CI Environments: In Windows Sandbox containers, CI runners (e.g.,

GitHub Actions self-hosted on Windows), and certain virtualized environments, the security
model is more restrictive. The Administrators group may be present but lack the specific
privileges needed for ACL manipulation.

  1. Stale Lock / Handle Contention: If a previous setup run crashed or was killed, file

handles or mutexes may still be held by orphaned processes, causing SetNamedSecurityInfoW
to fail because the directory is in use.

  1. Real User Resolution: The real_user field in the elevation payload (setup.rs:204)

defaults to std::env::var("USERNAME").unwrap_or_else(|_| "Administrators".to_string()).
In some environments (e.g., Windows Sandbox, service accounts), this may resolve to a
username that doesn't exist or can't be looked up, causing the resolve_sid(real_user)
call in lock_sandbox_dir to succeed but the resulting SID to not match the actual
token's groups.

1.3 Secondary Failure Point: ensure_allow_mask_aces_with_inheritance_impl() in acl.rs

File: codex-rs/windows-sandbox-rs/src/acl.rs, lines 307–376

The SetNamedSecurityInfoW call at line 342 also fails hard on error code 5. This function is
called during write ACE grants and deny ACE operations, and its failure propagates up as a
fatal error.

1.4 Why mode = "danger-full-access" Doesn't Resolve It

The run_setup_refresh() function in setup.rs (lines 114–119) correctly skips setup for
DangerFullAccess and ExternalSandbox:

if matches!(policy, SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }) {
    return Ok(());
}

However, the issue report states that setting mode = "danger-full-access" does NOT resolve the
problem. This indicates the setup is being invoked through a different code path that does
not check the policy:

  • run_setup_refresh_with_overrides() (setup.rs:134–139) does not check the policy and

always calls run_setup_refresh_inner().

  • The desktop app may use run_setup_refresh_with_extra_read_roots() which checks the policy

but the caller might pass a different policy object.

  • The legacy capture path (run_windows_sandbox_capture) in windows_impl (lib.rs:368–500)

does not go through run_setup_refresh at all — it uses prepare_legacy_spawn_context and
prepare_legacy_session_security directly, which may still invoke ACL operations.

1.5 Log Evidence

SetNamedSecurityInfoW sandbox dir failed: 5
helper_sandbox_lock_failed: lock sandbox bin dir C:\Users\Administrator\.codex\.sandbox-bin failed

The error code 5 is ERROR_ACCESS_DENIED from winerror.h. The path
C:\Users\Administrator\.codex\.sandbox-bin confirms the user is running as the built-in
Administrator account, which is the classic scenario for UAC token filtering issues.

---

2. Fix Approach

2.1 Fix 1: Graceful Fallback in lock_sandbox_dir() (Primary Fix)

File: codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs

Problem: lock_sandbox_dir() returns Err immediately when SetNamedSecurityInfoW fails,
causing the entire setup to abort.

Solution: When SetNamedSecurityInfoW returns ERROR_ACCESS_DENIED (5), log a warning
and continue with the existing permissions instead of failing. The sandbox directory already
exists (created by std::fs::create_dir_all), and the existing ACLs are likely sufficient
for the sandbox to function.

fn lock_sandbox_dir(
    dir: &Path,
    real_user: &str,
    sandbox_group_sid: &[u8],
    sandbox_group_access_mode: i32,
    sandbox_group_mask: u32,
    real_user_mask: u32,
    log: &mut File,
) -> Result<()> {
    std::fs::create_dir_all(dir)?;
    let system_sid = resolve_sid("SYSTEM")?;
    let admins_sid = resolve_sid("Administrators")?;
    let real_sid = resolve_sid(real_user)?;
    // ... build EXPLICIT_ACCESS_W entries and call SetEntriesInAclW ...

    let path_w = to_wide(dir.as_os_str());
    let res = SetNamedSecurityInfoW(
        path_w.as_ptr() as *mut u16,
        SE_FILE_OBJECT,
        DACL_SECURITY_INFORMATION,
        std::ptr::null_mut(),
        std::ptr::null_mut(),
        new_dacl,
        std::ptr::null_mut(),
    );
    if res != 0 {
        // NEW: Graceful fallback for ERROR_ACCESS_DENIED
        const ERROR_ACCESS_DENIED: u32 = 5;
        if res == ERROR_ACCESS_DENIED {
            // Log warning but don't fail — existing permissions are likely sufficient
            let _ = log_line(
                log,
                &format!(
                    "SetNamedSecurityInfoW on {} failed with ERROR_ACCESS_DENIED ({}); \
                     continuing with existing permissions. \
                     Consider running with elevated privileges or adjusting folder permissions.",
                    dir.display(),
                    res
                ),
            );
            // Clean up allocated resources
            if !new_dacl.is_null() {
                LocalFree(new_dacl as HLOCAL);
            }
            for sid in &sids {
                if !sid.is_null() {
                    LocalFree(*sid as HLOCAL);
                }
            }
            return Ok(());  // Continue instead of failing
        }
        return Err(anyhow::anyhow!(
            "SetNamedSecurityInfoW sandbox dir failed: {res}"
        ));
    }
    // ... cleanup ...
}

2.2 Fix 2: Graceful Fallback in ensure_allow_mask_aces_with_inheritance_impl() (Secondary Fix)

File: codex-rs/windows-sandbox-rs/src/acl.rs

Problem: The SetNamedSecurityInfoW call at line 342 fails hard on access denied, causing
write ACE grants to fail.

Solution: Add the same graceful fallback pattern:

// In ensure_allow_mask_aces_with_inheritance_impl(), around line 342:
let code3 = SetNamedSecurityInfoW(
    to_wide(path).as_ptr() as *mut u16,
    1, // SE_FILE_OBJECT
    DACL_SECURITY_INFORMATION,
    std::ptr::null_mut(),
    std::ptr::null_mut(),
    p_new_dacl,
    std::ptr::null_mut(),
);
if code3 == ERROR_SUCCESS {
    added = true;
} else {
    const ERROR_ACCESS_DENIED: u32 = 5;
    if code3 == ERROR_ACCESS_DENIED {
        // Log and continue — the ACE may already be present via inheritance
        // Don't treat this as a fatal error
    } else {
        if !p_new_dacl.is_null() { LocalFree(p_new_dacl as HLOCAL); }
        if !p_sd.is_null() { LocalFree(p_sd as HLOCAL); }
        return Err(anyhow!("SetNamedSecurityInfoW failed: {code3}"));
    }
}
if !p_new_dacl.is_null() { LocalFree(p_new_dacl as HLOCAL); }
if !p_sd.is_null() { LocalFree(p_sd as HLOCAL); }

2.3 Fix 3: Stale Lock File / Handle Cleanup

File: codex-rs/windows-sandbox-rs/src/bin/setup_main/win/read_acl_mutex.rs

Problem: If a previous setup run crashed, the mutex Local\CodexSandboxReadAcl may still
exist, causing subsequent runs to skip ACL operations. Additionally, file handles held by
orphaned processes can prevent ACL changes.

Solution: Add a cleanup mechanism that detects stale mutex state and attempts to clean up
before proceeding:

/// Attempt to clean up stale state from previous failed runs.
/// This includes orphaned mutex handles and stale lock files.
pub(super) fn cleanup_stale_lock_state() -> Result<()> {
    // The mutex is auto-cleaned when all handles are closed, so no explicit
    // cleanup is needed. However, we should ensure any file-based locks are
    // cleaned up. Currently there are no file-based locks, but this function
    // provides a hook for future lock mechanisms.
    Ok(())
}

Call this at the beginning of run_setup_full() before any ACL operations.

2.4 Fix 4: Ensure danger-full-access Mode Is Respected Everywhere

File: codex-rs/windows-sandbox-rs/src/setup.rs

Problem: run_setup_refresh_with_overrides() does not check the policy, so setup is
always attempted regardless of the sandbox mode.

Solution: Add policy check to run_setup_refresh_with_overrides():

pub fn run_setup_refresh_with_overrides(
    request: SandboxSetupRequest<'_>,
    overrides: SetupRootOverrides,
) -> Result<()> {
    // Skip setup for policies that don't use Windows sandbox
    if matches!(
        request.permissions.sandbox_policy(),
        SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
    ) {
        return Ok(());
    }
    run_setup_refresh_inner(request, overrides)
}

Also ensure the SandboxSetupRequest struct exposes the policy for this check.

2.5 Fix 5: Retry with Privilege Elevation

File: codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs

Problem: The setup binary may not have the required privileges (SE_RESTORE_NAME) to
modify ACLs.

Solution: Before calling SetNamedSecurityInfoW, attempt to enable the required
privileges. If that fails, fall back to the graceful degradation approach:

/// Attempt to enable SE_RESTORE_NAME privilege for the current process.
/// Returns true if the privilege was successfully enabled.
unsafe fn try_enable_restore_privilege() -> bool {
    use windows_sys::Win32::Security::{
        AdjustTokenPrivileges, LookupPrivilegeValueW, SE_RESTORE_NAME,
        TOKEN_ADJUST_PRIVILEGES, TOKEN_QUERY,
    };
    use windows_sys::Win32::System::Threading::{GetCurrentProcess, OpenProcessToken};

    let mut h_token: HANDLE = std::ptr::null_mut();
    if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &mut h_token) == 0 {
        return false;
    }

    let name_w = to_wide(OsStr::new(SE_RESTORE_NAME));
    let mut luid: windows_sys::Win32::Security::LUID = std::mem::zeroed();
    if LookupPrivilegeValueW(std::ptr::null(), name_w.as_ptr(), &mut luid) == 0 {
        CloseHandle(h_token);
        return false;
    }

    let mut tp: windows_sys::Win32::Security::TOKEN_PRIVILEGES = std::mem::zeroed();
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = windows_sys::Win32::Security::SE_PRIVILEGE_ENABLED;

    let result = AdjustTokenPrivileges(h_token, 0, &mut tp, 0, std::ptr::null_mut(), std::ptr::null_mut()) != 0
        && GetLastError() == 0;

    CloseHandle(h_token);
    result
}

---

3. Code-Level Fix Summary

Files to Modify

| File | Changes |
|------|---------|
| codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs | Fix 1 (graceful fallback in lock_sandbox_dir), Fix 5 (privilege elevation attempt) |
| codex-rs/windows-sandbox-rs/src/acl.rs | Fix 2 (graceful fallback in ensure_allow_mask_aces_with_inheritance_impl) |
| codex-rs/windows-sandbox-rs/src/bin/setup_main/win/read_acl_mutex.rs | Fix 3 (stale lock cleanup) |
| codex-rs/windows-sandbox-rs/src/setup.rs | Fix 4 (policy check in run_setup_refresh_with_overrides) |

Detailed Patches

Patch 1: win.rs — lock_sandbox_dir() graceful fallback
// In lock_sandbox_dir(), replace the error handling block at lines 370-373:
        if res != 0 {
            const ERROR_ACCESS_DENIED: u32 = 5;
            if res == ERROR_ACCESS_DENIED {
                // On some Windows configurations (UAC-filtered admin tokens,
                // Windows Sandbox, CI runners), SetNamedSecurityInfoW fails
                // with ERROR_ACCESS_DENIED even for Administrators. The
                // directory already exists with inherited permissions that are
                // typically sufficient for sandbox operation. Log a warning
                // and continue instead of failing the entire setup.
                let _ = log_line(
                    log,
                    &format!(
                        "SetNamedSecurityInfoW on {} failed with ERROR_ACCESS_DENIED; \
                         continuing with existing permissions",
                        dir.display()
                    ),
                );
                // Fall through to cleanup below
            } else {
                if !new_dacl.is_null() {
                    LocalFree(new_dacl as HLOCAL);
                }
                for sid in sids {
                    if !sid.is_null() {
                        LocalFree(sid as HLOCAL);
                    }
                }
                return Err(anyhow::anyhow!(
                    "SetNamedSecurityInfoW sandbox dir failed: {res}"
                ));
            }
        }
        // Cleanup (shared path for both success and graceful fallback)
        if !new_dacl.is_null() {
            LocalFree(new_dacl as HLOCAL);
        }
        for sid in sids {
            if !sid.is_null() {
                LocalFree(sid as HLOCAL);
            }
        }
Patch 2: acl.rs — ensure_allow_mask_aces_with_inheritance_impl() graceful fallback
// In ensure_allow_mask_aces_with_inheritance_impl(), around line 351:
            if code3 == ERROR_SUCCESS {
                added = true;
            } else {
                const ERROR_ACCESS_DENIED: u32 = 5;
                if code3 != ERROR_ACCESS_DENIED {
                    if !p_new_dacl.is_null() {
                        LocalFree(p_new_dacl as HLOCAL);
                    }
                    if !p_sd.is_null() {
                        LocalFree(p_sd as HLOCAL);
                    }
                    return Err(anyhow!("SetNamedSecurityInfoW failed: {code3}"));
                }
                // Access denied — the ACE may already be present via inheritance.
                // Don't treat this as a fatal error.
            }
Patch 3: setup.rs — Policy check in run_setup_refresh_with_overrides
// Add to SandboxSetupRequest or use existing permissions reference:
pub fn run_setup_refresh_with_overrides(
    request: SandboxSetupRequest<'_>,
    overrides: SetupRootOverrides,
) -> Result<()> {
    if matches!(
        request.permissions.sandbox_policy(),
        SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
    ) {
        return Ok(());
    }
    run_setup_refresh_inner(request, overrides)
}

---

4. Testing Plan

4.1 Unit Tests

| Test | Description | Expected Result |
|------|-------------|-----------------|
| test_lock_sandbox_dir_access_denied_fallback | Mock SetNamedSecurityInfoW to return error 5 | Function returns Ok(()) with warning logged |
| test_lock_sandbox_dir_other_error_fails | Mock SetNamedSecurityInfoW to return error 3 (path not found) | Function returns Err |
| test_ensure_allow_mask_access_denied_fallback | Mock SetNamedSecurityInfoW in ACL module to return error 5 | Function returns Ok(false) without adding ACE |
| test_danger_full_access_skips_setup | Call run_setup_refresh with DangerFullAccess policy | Returns Ok(()) immediately |
| test_overrides_with_danger_full_access | Call run_setup_refresh_with_overrides with DangerFullAccess | Returns Ok(()) immediately (new behavior) |

4.2 Integration Tests

| Test | Environment | Description |
|------|-------------|-------------|
| test_setup_as_builtin_admin | Windows with built-in Administrator account | Setup completes without ERROR_ACCESS_DENIED |
| test_setup_in_windows_sandbox | Windows Sandbox container | Setup completes or degrades gracefully |
| test_setup_ci_runner | GitHub Actions Windows runner | Setup completes or degrades gracefully |
| test_setup_with_stale_mutex | After killing setup process mid-run | Stale mutex is cleaned up, setup succeeds |
| test_danger_full_access_no_setup | Any Windows environment | No setup binary is spawned |

4.3 Manual Verification Steps

  1. Reproduce the original issue:
  • Run Codex on Windows as the built-in Administrator account
  • Observe SetNamedSecurityInfoW sandbox dir failed: 5 in logs
  • Confirm ~80-90% command failure rate
  1. Apply the fix and verify:
  • Build with the patched code
  • Run the same commands
  • Verify setup completes (or degrades gracefully)
  • Confirm commands execute successfully
  1. Verify danger-full-access mode:
  • Set mode = "danger-full-access" in config.toml
  • Verify no setup binary is spawned (check process list)
  • Verify commands execute without sandbox restrictions

4.4 Regression Testing

  • Verify existing sandbox functionality still works on non-problematic Windows configurations
  • Verify ACL-based read/write restrictions are still enforced where applicable
  • Verify firewall rules are still configured correctly
  • Verify sandbox users are still provisioned correctly

---

5. Impact Assessment

5.1 Risk Level: Low

The fix primarily adds graceful degradation rather than changing core behavior:

  • Existing behavior preserved: When SetNamedSecurityInfoW succeeds, nothing changes
  • New fallback path: Only activates on ERROR_ACCESS_DENIED, which currently causes a hard failure
  • No security regression: The fallback continues with existing permissions, which are inherited from the parent directory and typically include Administrator access

5.2 Affected Components

| Component | Impact |
|-----------|--------|
| lock_sandbox_dir() | Primary fix target — now degrades gracefully |
| ensure_allow_mask_aces_with_inheritance_impl() | Secondary fix target — now degrades gracefully |
| run_setup_refresh_with_overrides() | Now respects DangerFullAccess policy |
| Setup binary (codex-windows-sandbox-setup.exe) | Exit code 0 in more scenarios |
| Desktop app | Fewer "setup refresh failed" errors |

5.3 Security Considerations

  • No new privilege escalation: The fix does not attempt to elevate privileges beyond what the process already has
  • Existing permissions maintained: The fallback uses inherited ACLs, which are the same permissions the directory would have without the explicit DACL update
  • DangerFullAccess behavior: This mode already exists and is designed to bypass sandboxing; the fix just ensures it's properly respected

5.4 Performance Impact

  • Negligible: The fix adds a single error code comparison and log message in the failure path
  • No additional system calls: The privilege elevation attempt (Fix 5) is only tried once per setup run

5.5 Backward Compatibility

  • Fully backward compatible: The fix only changes behavior in the error path
  • No API changes: All function signatures remain the same
  • No config changes required: Users don't need to modify their configuration

---

6. Implementation Notes

6.1 Error Code Reference

| Code | Constant | Description |
|------|----------|-------------|
| 0 | ERROR_SUCCESS | Operation succeeded |
| 5 | ERROR_ACCESS_DENIED | Access denied (the bug) |
| 1314 | ERROR_PRIVILEGE_NOT_HELD | Required privilege not held |
| 3 | ERROR_PATH_NOT_FOUND | Path not found |

6.2 Related Code Paths

The following code paths also call SetNamedSecurityInfoW and should be reviewed for
similar issues:

  1. acl.rs:342 — ensure_allow_mask_aces_with_inheritance_impl() (covered by Fix 2)
  2. acl.rs:463 — add_allow_ace() — already handles errors but could benefit from graceful fallback
  3. acl.rs:500+ — add_deny_write_ace() / add_deny_read_ace() — same pattern

6.3 Logging Recommendations

When the graceful fallback is triggered, the log message should include:

  • The directory path that failed
  • The error code
  • A suggestion to run with elevated privileges or adjust folder permissions
  • A note that setup is continuing with existing permissions

This helps users and support teams understand what happened without causing alarm.

---

7. Deliverables

  1. Patched source files (4 files modified)
  2. Unit tests (5 new tests)
  3. Integration test scenarios (5 scenarios)
  4. Updated documentation for danger-full-access mode behavior
  5. Release notes entry describing the fix

---

8. References

warren2008-2020-spec · 1 month ago

I published a small read-only diagnostic CLI for Codex setup issues that might be useful when collecting environment information for Windows sandbox failures:

npx --yes codex-doctor

Repo: https://github.com/warren2008-2020-spec/codex-doctor
npm: https://www.npmjs.com/package/codex-doctor

It does not modify Codex or the sandbox. It only reports local signals such as:

  • Windows/WSL platform state
  • Node and npm availability/auth
  • Git and GitHub CLI availability/auth
  • Codex CLI availability
  • Codex config presence and WSL-mode hints
  • proxy / NO_PROXY hints
  • CI environment hints

For issues like this one, my intent is to make it easier to paste a safe setup report without exposing tokens or private config. If there are specific Windows sandbox checks that would help triage this failure mode, I can add them.