DeepSeek Harness workspace-write 0xC0000142: default DACL
Switch DeepSeek Harness to workspace-write on Windows and every shell child process returns 0xC0000142, while the same command runs fine under read-only. In cases that fail only under workspace-write, the root cause usually sits in the restricted token's default DACL: workspace-write writes a derived capability SID into TokenDefaultDacl, while read-only writes the world SID. The hard part is not the conclusion but the evidence — the two modes change two token fields at once, so a plain comparison cannot separate the restricting list from the default DACL. The community nailed it with a single-variable experiment that overrode only the default DACL (#11223, #11448).
DeepSeek Harness: Subtract first: turn "two things changed at once" into one variable
read-only and workspace-write differ not only in the default DACL but also in the restricting SID list; as long as both change together, any comparison only tells you "workspace-write is broken" and cannot attribute it to a specific field.
Start by reproducing a minimal control:
- Create an empty directory as the workspace and put a single
echo 1test script in it. - Switch to read-only, run
echo 1, and confirm it returns normally. - Switch to workspace-write, run the same command, and confirm it returns
0xC0000142with no output. - Record the full exit code and timing for both runs; do not rely on the UI's word "failed".
Then run the single-variable experiment. The idea: let DSH build the token exactly as it normally would, and override only TokenDefaultDacl after construction, leaving every other field untouched.
- Open a debug terminal with administrator rights, start DSH, and reproduce the failure.
- Find the parent of the failing child process and confirm which restricted token it uses.
- Replace only that token's
TokenDefaultDaclwithS-1-5-11(Authenticated Users) or the current logon SID. - Leave the restricting SID list, integrity level, and session ID completely unchanged, then start the child again.
- If it starts, the default DACL is the root cause; if it still returns
0xC0000142, go back to the restricting list or the console.
The value here is elimination: change one thing, observe one result, and the conclusion holds. The community initially guessed that "the capability SID has no read ACE on System32" and later withdrew it precisely because of this experiment — the deciding factor was the default DACL.
DSH plugin: Root cause: the default DACL names a derived capability SID
setTokenDefaultDaclGrant(api, restrictedToken, this.tempWriteSidPtr ?? this.writeSidPtr ?? worldSid) at sandbox-windows-acl/src/index.ts:304 decides which SID goes into the default DACL; under workspace-write it resolves to the derived capability SID, and under read-only to the world SID.
Unroll the call path:
- Entering workspace-write, DSH needs temporary write access and prepares
tempWriteSid/writeSid. - After building the restricted token, it grants the default DACL to that capability SID.
- When the child creates objects, they inherit this DACL by default.
- But the child must read system paths much earlier, during DLL initialization; the capability SID has no read ACE on those paths, so initialization fails outright.
- The failure surfaces as
0xC0000142because the process never reaches the point of running the command.
The comment above the call (index.ts:301-303) states the intent: objects created in a session temp directory should not receive shared-workspace capability. In other words, the capability SID is not a typo — it is deliberate. The problem is that the same SID is also used as the default DACL required for process startup, which is too narrow and stops the child before initialization finishes.
DeepSeek Harness: Why you cannot just swap in the world SID
Changing the default DACL to S-1-5-11 or Everyone does let the process start, but it tears out the isolation that keeps temp-directory objects from inheriting shared-workspace capability; the better fix adds the logon SID alongside the capability SID rather than replacing it.
The three candidates compare like this:
| Candidate SID | Child starts? | Isolation | Verdict |
|---|---|---|---|
| Derived capability SID (current) | No | Strongest | Needs a broader SID added |
S-1-5-11 / Everyone | Yes | Weakest, visible across sessions | Fine for verification, not a fix |
| Current logon SID | Yes | Strong, still isolated across sessions | Recommended direction |
The community recommendation is to keep both the capability SID and the logon SID in the default DACL. Temp-directory objects still cannot get shared-workspace capability, but the basic read permission the child needs to start is present. findLogonSid already exists in token.ts in the same package and is already imported at index.ts:55, so the change is small.
DSH Plugin: What users can do: no switch, so change host or wait
There is no user-facing configuration that changes the default DACL; the only immediate recoveries are changing the host or temporarily opening the sandbox, and keeping workspace-write means waiting for the core fix.
Ordered by cost, lowest first:
- Switch to
dsh web: the Node host does not go through this desktop restricted-token chain, so commands under workspace-write usually run normally; the cost is accepting a browser-based workflow. - Temporarily use
danger-full-access: commands run, but sandbox isolation is gone, so only use it briefly on trusted projects. - Move to a machine or account without the problem: for a one-off delivery, shifting the task to Linux or macOS sidesteps the Windows token differences.
- Wait for the core fix: watch whether default DACL construction becomes "capability SID + logon SID"; do not expect an rc point release to carry it.
If you have a source checkout, you can patch it yourself: append the logon SID at the setTokenDefaultDaclGrant call site, then run three checks — echo 1, a file write, and a cross-session access. Verifying only that "the command runs" is not enough; confirm cross-session isolation is still intact.
DeepSeek Harness: How it differs from the other two 0xC0000142 families
The default DACL case is identified by "only workspace-write fails, read-only works, and the account is not the built-in Administrator"; satisfy all three before digging further, and do not start by editing tokens.
| Signal | Default DACL | Built-in Administrator | Console issue |
|---|---|---|---|
| Account SID | Any | Ends in -500 | Any |
| read-only works? | Yes | Usually also fails | Usually also fails |
dsh web works? | Yes | Yes | Yes |
| Key evidence | Overriding only the default DACL restores it | Upgrading to alpha.2 restores it | Not creating a new console restores it |
Run all three checks before deciding whether to touch the token. Change several variables at once and you end up with the vague conclusion that "it seems a bit better".
DSH plugin: Cautions: four traps when experimenting
Experiment on a copy of the token, never on a running task, and keep the SID choice as narrow as possible.
- Do not edit tokens in a production session. Use a separate test workspace and test account so you do not take down a running task.
- Do not verify with
echo 1alone. Also test file writes, reads of system paths, and cross-session access to confirm the fix did not remove isolation. - Do not treat
S-1-5-11as the final answer. It is only suitable for single-variable verification; the scope is far too wide. - Do not ignore version differences. Line numbers in
index.tsmove between rc builds, so locate code by the function namesetTokenDefaultDaclGrant, not by memorized line numbers.
What makes this problem annoying is that it looks like insufficient permissions when the token is simply built too narrowly. Pin the root cause with a single-variable experiment first, then decide whether to change the host, wait for the fix, or patch in the logon SID yourself — do not bounce between account, ACL, and console theories.See DSH plugin: Windows subprocess fails with 0xC0000142 for the related case.
FAQ
When DeepSeek Harness shells fail only under workspace-write, suspect the restricted token's default DACL first: under workspace-write, setTokenDefaultDaclGrant uses a derived capability SID, while read-only uses the world SID. The capability SID has no read ACE on some system paths, so the child dies during DLL initialization and returns 0xC0000142.
DeepSeek Harness keeps the default DACL narrow because that field exists to stop objects created in the session temp directory from receiving shared-workspace capability. Replacing it with S-1-5-11 (Authenticated Users) is far too broad and effectively removes that isolation. Add the logon SID alongside the capability SID instead, so children start while cross-session isolation stays.
A clean single-variable test is hard because DeepSeek Harness switches read-only and workspace-write in two places at once: the restricting list and the default DACL, so a direct comparison cannot attribute the failure. Keep the restricting list unchanged, override only TokenDefaultDacl to the logon SID or S-1-5-11, then start the child; only if that one change fixes it is the default DACL the root cause.
No, DeepSeek Harness exposes no direct option that lets normal users bypass this today; practical alternatives are switching to dsh web, whose Node host does not use this desktop token chain, or temporarily using danger-full-access. To keep workspace-write you have to wait for the core change to the default DACL or patch it yourself in a source checkout.
With 0xC0000142 under workspace-write, DeepSeek Harness triage first checks whether the account SID ends in -500 to rule out LUA_TOKEN, then compares desktop and dsh web behavior to rule out console creation flags, and only then runs the single-variable default DACL override. Keep that order; changing several variables at once leaves results you cannot explain.
Related Terms
- TokenDefaultDacl
- TokenDefaultDacl is the default DACL field of a Windows access token and determines the access control entries inherited by objects the token creates. DeepSeek Harness writes a derived capability SID here under workspace-write to keep temp-directory objects from inheriting shared-workspace capability.— https://github.com/deepseek-ai/deepseek-harness/discussions/11448
- derived capability SID
- A derived capability SID is a capability SID generated by `CreateRestrictedToken` (usually starting with `S-1-4-`) that narrows access to a specific capability set. It is not a user or group SID, and it has no read ACE on some system paths.— https://github.com/deepseek-ai/deepseek-harness/discussions/11223
- logon SID
- A logon SID is the Windows logon-session SID (`S-1-5-5-X-Y`) that identifies one specific logon. It is narrower than `Authenticated Users` and closer to the permissions a normal process needs, which makes it the usual minimal fix candidate for a default DACL.— https://github.com/deepseek-ai/deepseek-harness/discussions/11448
- restricting SID list
- The restricting SID list is the restricting SIDs parameter of `CreateRestrictedToken` and defines extra access checks a restricted token must pass. It is a separate part from the default DACL, so diagnosis has to change them independently or you cannot tell which one broke the child.— https://github.com/deepseek-ai/deepseek-harness/discussions/11223
Sources
- #11223 — Windows workspace-write: 0xC0000142 comes from the token default DACL· deepseek-ai (GitHub Discussions)
- #11448 — Windows 10: workspace-write sandbox kills every child process with 0xC0000142· deepseek-ai (GitHub Discussions)
- #11179 — workspace-write sandbox makes every shell child process fail with 0xC0000142· deepseek-ai (GitHub Discussions)
- deepseek-ai/deepseek-harness (source repository)· GitHub