JuliusBrussee/caveman · error
native runtime listen: %w
Error message
native runtime listen: %w
What it means
Returned when net.Listen("unix", path) fails while the native runtime is trying to bind its local Unix socket. The server had just cleaned (or verified absent) a stale socket, so this usually means the path is unwritable, too long, or another process created a socket between the stale check and the listen.
Source
Thrown at proxy/internal/nativeruntime/server_unix.go:56
}
if err := os.Chmod(filepath.Dir(path), 0o700); err != nil {
return fmt.Errorf("native runtime chmod dir: %w", err)
}
if _, err := os.Stat(path); err == nil {
conn, dialErr := net.DialTimeout("unix", path, 50*time.Millisecond)
if dialErr == nil {
_ = conn.Close()
return errors.New("native runtime: socket already active")
}
if err := os.Remove(path); err != nil {
return fmt.Errorf("native runtime remove stale socket: %w", err)
}
} else if !os.IsNotExist(err) {
return fmt.Errorf("native runtime inspect socket: %w", err)
}
listener, err := net.Listen("unix", path)
if err != nil {
return fmt.Errorf("native runtime listen: %w", err)
}
defer listener.Close()
defer os.Remove(path)
if err := os.Chmod(path, 0o600); err != nil {
return fmt.Errorf("native runtime chmod socket: %w", err)
}
go func() {
<-ctx.Done()
_ = listener.Close()
}()
for {
conn, err := listener.Accept()
if err != nil {
if ctx.Err() != nil {
return nil
}
return fmt.Errorf("native runtime accept: %w", err)
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Check that the socket's parent directory (home/run or equivalent) exists and is writable by the current user
- Ensure no second caveman process is already serving the same home (lsof on the socket path); stop it or use a different home
- Shorten the socket path — put home closer to the filesystem root or raise the home directory if the path exceeds the OS sun_path limit
- If the directory is on a filesystem that does not support Unix sockets (some network mounts), move home to a local filesystem
Example fix
// before: home deep under a long path, listen fails with 'invalid argument' home := "/very/long/nested/path/that/exceeds/unix/socket/limits/.caveman" err := nativeruntime.Serve(ctx, home, rt) // after: keep the socket path short home := "/home/user/.caveman" err := nativeruntime.Serve(ctx, home, rt)
Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Dir(sockPath)
if info, err := os.Stat(dir); err != nil || !info.IsDir() {
return fmt.Errorf("socket directory %s missing", dir)
}
if len(sockPath) >= 104 { // typical sun_path limit
return fmt.Errorf("socket path too long (%d bytes)", len(sockPath))
} Try / catch
if err := nativeruntime.Serve(ctx, home, rt); err != nil {
if strings.Contains(err.Error(), "native runtime listen") {
// inspect %w chain: errors.Is(err, os.ErrPermission) vs syscall.EADDRINUSE
}
return err
} Prevention
- Create the socket's parent directory with 0700 before starting Serve
- Keep the home directory path short; avoid deeply nested homes on Unix
- Run one server per home; probe with a dial first if unsure
When it happens
Trigger: Calling nativeruntime.Serve on Unix when (a) the parent directory of the socket path does not exist or lacks write permission, (b) the socket path exceeds the ~104-108 byte sun_path limit, or (c) a second caveman process started concurrently and won the listen race after the stale-socket probe.
Common situations: HOME points to a read-only or non-existent directory; a leftover-but-active listener from an earlier run (socket-active check passed only for a dead peer); running two instances with the same home; deeply nested home paths blowing past the Unix socket path-length limit.
Related errors
- native runtime: socket already active
- native runtime mkdir: %w
- cache-replay: verifier command must be an existing regular f
- native runtime: invalid decision id
- native runtime: invalid decision record
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/44058c79dbd7cd92.
Report an issue: GitHub.