zeroclaw-labs/zeroclaw · error
local IPC endpoint lock {} is not a regular file; remove it
Error message
local IPC endpoint lock {} is not a regular file; remove it or choose a different socket path What it means
The pre-existing entry at `<socket>.lock` is not a regular file (it is a directory, FIFO, device, etc.). The lock protocol requires a regular file because the advisory flock and the dev/inode identity check only make sense on one; a non-regular entry could also be a DoS vector.
Source
Thrown at crates/zeroclaw-runtime/src/rpc/local.rs:326
Restrict it (chmod go-w or +t) or point ZEROCLAW_SOCKET at a \
private directory",
parent.display()
);
}
Ok(())
}
/// Rejects pre-existing lock entries that do not provide the guarantees a
/// freshly created lock would have.
///
/// The inode must be a regular file owned by the current user with no
/// group/other access, and still linked at the time of inspection. A
/// foreign-owned or permissive entry could be locked by another local
/// user to block startup, or unlinked and recreated by its owner to hand
/// two daemons different lock inodes.
fn require_trusted_lock_file(metadata: &Metadata, lock_path: &Path) -> Result<()> {
if !metadata.file_type().is_file() {
anyhow::bail!(
"local IPC endpoint lock {} is not a regular file; remove it \
or choose a different socket path",
lock_path.display()
);
}
let euid = unsafe { libc::geteuid() };
if metadata.uid() != euid {
anyhow::bail!(
"local IPC endpoint lock {} is owned by uid {}, not the \
daemon user; remove it or choose a different socket path",
lock_path.display(),
metadata.uid()
);
}
if metadata.mode() & 0o077 != 0 {
anyhow::bail!(
"local IPC endpoint lock {} is accessible to other users \
(mode {:o}); restrict it to 0600 or remove it",View on GitHub (pinned to 88bb9c8533)
Solutions
- Inspect the entry: ls -la <socket>.lock and file <socket>.lock.
- Remove the offending entry (rm -rf for a dir, rm for a fifo).
- Or point ZEROCLAW_SOCKET at a different path so a fresh lock file is created.
- Check for the script/tool that created the non-file so it does not reappear.
Example fix
# before: zeroclaw.sock.lock is a directory ls -ld /run/zeroclaw/zeroclaw.sock.lock # drwxr-xr-x ... # after rm -rf /run/zeroclaw/zeroclaw.sock.lock systemctl restart zeroclaw
Defensive patterns
Strategy: validation
Validate before calling
fn lock_entry_is_regular(sock: &std::path::Path) -> bool {
let mut s = sock.as_os_str().to_os_string();
s.push(".lock");
std::fs::symlink_metadata(std::path::PathBuf::from(s))
.map(|m| m.file_type().is_file())
.unwrap_or(true) // absent is fine: daemon will create it
} Try / catch
if !lock_entry_is_regular(&sock_path) {
anyhow::bail!("<socket>.lock exists but is not a regular file; remove it");
} Prevention
- Never pre-create the .lock entry; let the daemon create it.
- Keep runtime dirs managed solely by the daemon, not ad-hoc scripts.
When it happens
Trigger: Someone created a directory or named pipe at the exact lock path (mkdir $(dirname sock)/zeroclaw.sock.lock, mkfifo ...); a broken cleanup script or artifact moved a non-file onto the path; symlinks are already rejected earlier at open via O_NOFOLLOW, so this catches other file types.
Common situations: Accidental 'mkdir' instead of 'touch' when pre-creating runtime dirs; leftover objects from experimentation; hostile or buggy co-tenant in a shared directory.
Related errors
- local IPC endpoint lock {} was unlinked while being opened
- local IPC endpoint lock directory {} is owned by uid {}; it
- local IPC endpoint lock {} is owned by uid {}, not the daemo
- local IPC endpoint lock {} is accessible to other users (mod
- local IPC endpoint lock {} was replaced while being acquired
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/99e08b9d17d07a78.
Report an issue: GitHub.