{"record":{"id":"c5c206265c694444","repo":"herdrdev/herdr","slug":"ssh-control-socket-path-exceeds-the-unix-socket-le","errorCode":null,"errorMessage":"SSH control socket path exceeds the Unix socket length limit","messagePattern":"SSH control socket path exceeds the Unix socket length limit","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src/platform/unix_common.rs","lineNumber":69,"sourceCode":"                Ok(()) => return Ok(dir),\n                Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => continue,\n                Err(err) => {\n                    last_error = Some(err);\n                    break;\n                }\n            }\n        }\n    }\n\n    if let Some(err) = last_error {\n        return Err(err);\n    }\n    let message = if path_fits {\n        \"failed to create private herdr ssh config directory\"\n    } else {\n        \"SSH control socket path exceeds the Unix socket length limit\"\n    };\n    Err(std::io::Error::new(\n        if path_fits {\n            std::io::ErrorKind::AlreadyExists\n        } else {\n            std::io::ErrorKind::InvalidInput\n        },\n        message,\n    ))\n}\n\npub(crate) fn create_remote_ssh_config_file(path: &Path) -> std::io::Result<std::fs::File> {\n    use std::os::unix::fs::OpenOptionsExt;\n\n    std::fs::OpenOptions::new()\n        .write(true)\n        .create_new(true)\n        .mode(0o600)\n        .open(path)\n}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/herdrdev/herdr/blob/f457cff4f2648eee85d176f8a41861241d4e8428/src/platform/unix_common.rs#L51-L87","documentation":"On Unix, Herdr computes the SSH control socket path inside the private config directory and validates it against the OS sun_path length limit (~108 bytes). If the computed socket path is too long, this InvalidInput error is returned instead of attempting creation, so the overlong path never reaches bind(). The sibling message 'failed to create private herdr ssh config directory' (AlreadyExists) covers the short-path exhaustion case.","triggerScenarios":"Calling create_remote_ssh_config_dir when the resolved control socket path (private dir + socket name) exceeds the platform's Unix domain socket address limit. Deeper home directories (nested Nix store paths, long usernames, deeply mounted home) push the path over the limit.","commonSituations":"Long HOME paths (e.g. /mnt/data/users/very-long-username/.local/share/herdr/...), Nix store builds, or tests like remote_ssh_config_dir_rejects_overlong_control_socket_name that deliberately construct an overlong name.","solutions":["Shorten the path: set HOME or the relevant XDG/herdr data dir to a shorter location (e.g. /tmp/herdr or a shallower home)","Move the SSH config dir to a shorter base directory if Herdr's config allows overriding it","On Linux, ipcs-agnostic workaround: none reliable — the limit is in the kernel ABI; shortening the path is the fix","If you control the tests, keep socket names short like the repo's own rejection test does"],"exampleFix":"// before\nexport HOME=/mnt/vault/users/alexandria-thornton/long/nested/home\n// after\nexport HOME=/home/alex","handlingStrategy":"validation","validationCode":"const UNIX_SOCK_LIMIT: usize = 108; // typical sun_path size; query at runtime if possible\nlet socket_path = private_dir.join(control_socket_name);\nif socket_path.as_os_str().len() >= UNIX_SOCK_LIMIT {\n    // choose a shorter private dir (e.g. under /tmp) before calling\n}","typeGuard":null,"tryCatchPattern":"Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains(\"Unix socket length limit\") => {\n    // reconfigure herdr's data dir to a shorter path and retry once\n}","preventionTips":["Keep HOME/herdr data paths short, especially in CI and containers","Expose a config override for the SSH control socket base directory","Fail fast at config load when the computed socket path nears the limit"],"tags":["ssh","unix-socket","path-length","limit","invalid-input"],"backgroundTag":"unix-socket-path-too-long","analyzedSha":"f457cff4f2648eee85d176f8a41861241d4e8428","analyzedAt":"2026-08-28T15:41:09.197Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}