block/buzz · error
Failed to bind UDS {uds_path}: {e}
Error message
Failed to bind UDS {uds_path}: {e} What it means
After the stale-socket cleanup, serve() calls tokio::net::UnixListener::bind(BUZZ_UDS_PATH) and wraps the io::Error. At this point the path is known to be free, so failures come from the environment: parent directory missing (NotFound), no write permission on the directory (PermissionDenied, common when running non-root without a writable /run), the path exceeding the kernel's ~107-byte sun_path limit (InvalidInput on Linux), or a filesystem that does not support unix sockets.
Source
Thrown at crates/buzz-relay/src/main.rs:1350
.map_err(|e| anyhow::anyhow!("Failed to bind {}: {e}", config.bind_addr))?;
info!(addr = %config.bind_addr, "buzz-relay TCP listening");
#[cfg(unix)]
if let Some(ref uds_path) = config.uds_path {
use std::os::unix::fs::FileTypeExt as _;
match std::fs::symlink_metadata(uds_path) {
Ok(meta) if meta.file_type().is_socket() => {
let _ = std::fs::remove_file(uds_path);
}
Ok(_) => {
return Err(anyhow::anyhow!(
"BUZZ_UDS_PATH {uds_path} exists but is not a socket"
));
}
Err(_) => {}
}
let uds_listener = tokio::net::UnixListener::bind(uds_path)
.map_err(|e| anyhow::anyhow!("Failed to bind UDS {uds_path}: {e}"))?;
info!(path = %uds_path, "buzz-relay UDS listening");
let router_uds = router.clone();
let mut uds_rx = shutdown_tx.subscribe();
let uds_handle = tokio::spawn(async move {
axum::serve(uds_listener, router_uds.into_make_service())
.with_graceful_shutdown(async move {
uds_rx.changed().await.ok();
})
.await
.ok();
});
let mut tcp_rx = shutdown_tx.subscribe();
axum::serve(
tcp_listener,
router.into_make_service_with_connect_info::<std::net::SocketAddr>(),
)View on GitHub (pinned to f956e6fe06)
Solutions
- Create the parent directory: mkdir -p /run/buzz (entrypoint or Dockerfile) and rerun.
- Fix ownership/permissions so the relay user can write there (chown/chmod), or use a writable path like /tmp.
- Shorten the path — keep the full absolute path well under ~104 characters.
- Move the socket to a local or tmpfs filesystem if the current mount does not support sockets.
Example fix
# before: Error: Failed to bind UDS /run/buzz/relay.sock: No such file or directory (os error 2) # after: create the dir in the image/entrypoint RUN mkdir -p /run/buzz && chown relay:relay /run/buzz
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: the parent dir must exist and the path must fit sun_path (~104 bytes on Linux).
fn uds_bindable(path: &str) -> bool {
let p = std::path::Path::new(path);
match p.parent() {
Some(dir) => dir.is_dir() && path.len() < 104,
None => false,
}
}
if let Some(uds) = std::env::var("BUZZ_UDS_PATH").ok() {
assert!(uds_bindable(&uds), "{uds} not bindable — mkdir -p the parent, check perms, shorten the path");
} Type guard
fn classify_uds_bind_error(e: &std::io::Error) -> &'static str {
match e.kind() {
std::io::ErrorKind::NotFound => "parent directory missing",
std::io::ErrorKind::PermissionDenied => "no write permission on directory",
std::io::ErrorKind::InvalidInput => "path too long for sun_path",
_ => "filesystem may not support unix sockets",
}
} Try / catch
let uds_listener = match tokio::net::UnixListener::bind(uds_path) {
Ok(l) => l,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
return Err(anyhow!("parent dir missing for {uds_path}: mkdir -p it first"))
}
Err(e) => return Err(anyhow!("Failed to bind UDS {uds_path}: {e}")),
}; Prevention
- Entrypoints: mkdir -p the socket directory (and chown it to the relay user) before exec
- Keep UDS paths short and on tmpfs (/run) in containers
- For readonly-root images, mount an emptyDir/tmpfs at the socket directory
When it happens
Trigger: BUZZ_UDS_PATH=/run/buzz/relay.sock when /run/buzz does not exist; relay user lacking write access to /run or /var/run; deeply nested container paths (long overlayfs/kubelet pod paths) blowing past sun_path; socket placed on an NFS or otherwise socket-hostile mount; readonly-root filesystem with no writable socket dir.
Common situations: Containers running as non-root without tmpfs at /run; missing mkdir -p in entrypoints; distroless images with no pre-created runtime dirs; socket paths under /var/lib/kubelet/pods/... in hostPath mounts.
Related errors
- BUZZ_UDS_PATH {uds_path} exists but is not a socket
- git conformance probe failed: {e}
- Failed to bind health port {}: {e}
- Failed to bind {}: {e}
- mesh endpoint bind on {} failed: {e}
AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16).
Data as JSON: /api/errors/06b4ceae38e125b7.
Report an issue: GitHub.