herdrdev/herdr · error · io::Error

SSH control socket path exceeds the Unix socket length limit

Error message

SSH control socket path exceeds the Unix socket length limit

What it means

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.

Source

Thrown at src/platform/unix_common.rs:69

                Ok(()) => return Ok(dir),
                Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => continue,
                Err(err) => {
                    last_error = Some(err);
                    break;
                }
            }
        }
    }

    if let Some(err) = last_error {
        return Err(err);
    }
    let message = if path_fits {
        "failed to create private herdr ssh config directory"
    } else {
        "SSH control socket path exceeds the Unix socket length limit"
    };
    Err(std::io::Error::new(
        if path_fits {
            std::io::ErrorKind::AlreadyExists
        } else {
            std::io::ErrorKind::InvalidInput
        },
        message,
    ))
}

pub(crate) fn create_remote_ssh_config_file(path: &Path) -> std::io::Result<std::fs::File> {
    use std::os::unix::fs::OpenOptionsExt;

    std::fs::OpenOptions::new()
        .write(true)
        .create_new(true)
        .mode(0o600)
        .open(path)
}

View on GitHub (pinned to f457cff4f2)

Solutions

  1. Shorten the path: set HOME or the relevant XDG/herdr data dir to a shorter location (e.g. /tmp/herdr or a shallower home)
  2. Move the SSH config dir to a shorter base directory if Herdr's config allows overriding it
  3. On Linux, ipcs-agnostic workaround: none reliable — the limit is in the kernel ABI; shortening the path is the fix
  4. If you control the tests, keep socket names short like the repo's own rejection test does

Example fix

// before
export HOME=/mnt/vault/users/alexandria-thornton/long/nested/home
// after
export HOME=/home/alex
Defensive patterns

Strategy: validation

Validate before calling

const UNIX_SOCK_LIMIT: usize = 108; // typical sun_path size; query at runtime if possible
let socket_path = private_dir.join(control_socket_name);
if socket_path.as_os_str().len() >= UNIX_SOCK_LIMIT {
    // choose a shorter private dir (e.g. under /tmp) before calling
}

Try / catch

Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains("Unix socket length limit") => {
    // reconfigure herdr's data dir to a shorter path and retry once
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of herdrdev/herdr@f457cff4f2 (2026-08-28). Data as JSON: /api/errors/c5c206265c694444. Report an issue: GitHub.