JuliusBrussee/caveman · error
native runtime current user SID: unavailable
Error message
native runtime current user SID: unavailable
What it means
On Windows, Serve builds an owner-only SDDL ACL from the current process token's user SID. If GetTokenUser succeeds but returns nil user or nil SID, the security descriptor cannot be constructed and the pipe cannot be safely restricted to one user, so Serve fails closed instead of opening an unsecured pipe.
Source
Thrown at proxy/internal/nativeruntime/server_windows.go:46
}
func dialNativeRuntime(ctx context.Context, home string) (net.Conn, error) {
return winio.DialPipeContext(ctx, SocketPath(home))
}
// Serve exposes the same bounded JSON protocol over a user-only Windows named
// pipe. go-winio rejects remote clients at pipe creation; explicit owner SID
// ACL prevents another local user from attaching.
func Serve(ctx context.Context, home string, runtime *Runtime) error {
if runtime == nil || runtime.store == nil {
return errors.New("native runtime: store is required")
}
user, err := windows.GetCurrentProcessToken().GetTokenUser()
if err != nil {
return fmt.Errorf("native runtime current user SID: %w", err)
}
if user == nil || user.User.Sid == nil {
return errors.New("native runtime current user SID: unavailable")
}
sddl := "D:P(A;;GA;;;" + user.User.Sid.String() + ")"
listener, err := winio.ListenPipe(SocketPath(home), &winio.PipeConfig{
SecurityDescriptor: sddl,
InputBufferSize: maxRequestBytes,
OutputBufferSize: maxRequestBytes,
})
if err != nil {
return fmt.Errorf("native runtime named-pipe listen: %w", err)
}
defer listener.Close()
go func() {
<-ctx.Done()
_ = listener.Close()
}()
for {
conn, err := listener.Accept()
if err != nil {View on GitHub (pinned to 27d5a3981a)
Solutions
- Run the runtime under a normal user account with a well-formed token (interactive user or standard service account)
- If running as a service, configure the service logon account so the process token carries a user SID
- Check for impersonation in the parent process that may have replaced the process token
Example fix
// before: launching via a wrapper that calls ImpersonateNamedPipeClient before Serve // token has no owner SID -> error // after: call Serve on a process whose own token carries the user SID err := nativeruntime.Serve(ctx, home, rt) // run directly under the user account, not under impersonation
Defensive patterns
Strategy: fallback
Try / catch
if err := nativeruntime.Serve(ctx, home, rt); err != nil {
if strings.Contains(err.Error(), "SID: unavailable") {
// relaunch under a normal user account / unmodified service token
}
} Prevention
- Run the runtime under a standard user or service account with a complete process token
- Avoid launching Serve from impersonated or heavily stripped token contexts
When it happens
Trigger: Running the runtime under an account whose token exposes no user SID — some service accounts, sandboxed contexts, or tokens mangled by privilege-dropping/impersonation; unusual Windows container or SSH-session token configurations.
Common situations: Running as SYSTEM via a custom service wrapper that strips token info; running inside restricted containers (Server Core variants, sandboxing products); CI agents with modified token privileges.
Related errors
- native runtime current user SID: %w
- native runtime named-pipe listen: %w
- cannot safely launch Windows command shim: ${executable}
- cannot safely launch non-Node Windows command shim: ${execut
- cannot safely launch Windows command shim: ${command}
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/abf55e94e407d85a.
Report an issue: GitHub.