wezterm/wezterm · warning
failed to create symlink {} -> {}: {err:#}
Error message
failed to create symlink {} -> {}: {err:#} What it means
Logged by AgentProxy (mux/src/ssh_agent.rs:72, update_symlink) when creating the runtime symlink agent.<PID> -> SSH_AUTH_SOCK fails with an error other than AlreadyExists. On Windows this is almost always the missing 'Create symbolic links' privilege; on Unix it is permission problems in the runtime directory or a read-only filesystem. The message embeds both paths plus the chained io error, and note the initial-symlink failure is only logged, not propagated: the AgentProxy keeps running without a working agent link.
Source
Thrown at mux/src/ssh_agent.rs:72
fn update_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> anyhow::Result<()> {
let original = original.as_ref();
let link = link.as_ref();
match symlink_file(original, link) {
Ok(()) => Ok(()),
Err(err) => {
if err.kind() == std::io::ErrorKind::AlreadyExists {
std::fs::remove_file(link)
.with_context(|| format!("failed to remove {}", link.display()))?;
symlink_file(original, link).with_context(|| {
format!(
"failed to create symlink {} -> {}: {err:#}",
link.display(),
original.display()
)
})
} else {
anyhow::bail!(
"failed to create symlink {} -> {}: {err:#}",
link.display(),
original.display()
);
}
}
}
}
impl AgentProxy {
pub fn new() -> Self {
let pid = unsafe { libc::getpid() };
let sock_path = config::RUNTIME_DIR.join(format!("agent.{pid}"));
if let Some(inherited) = Self::default_ssh_auth_sock() {
if let Err(err) = update_symlink(&inherited, &sock_path) {
log::error!("failed to set {sock_path:?} to initial inherited SSH_AUTH_SOCK value of {inherited:?}: {err:#}");
}View on GitHub (pinned to 9c04f79f86)
Solutions
- On Windows: enable Developer Mode or grant the user/group the 'Create symbolic links' right (secpol.msc -> Local Policies -> User Rights Assignment)
- Fix permissions on the runtime dir (usually $XDG_RUNTIME_DIR/wezterm or the platform equivalent) so your user can write
- If a stale agent.<PID> file blocks the retry path, remove it and restart wezterm
- Set/repair SSH_AUTH_SOCK to a valid agent socket so the initial symlink target is sane
Example fix
# before: unprivileged Windows user
> wezterm.exe # log: failed to create symlink ... agent.<PID>
# after: grant the right (admin shell)
> secpol.msc # Local Policies -> User Rights Assignment ->
# 'Create symbolic links' -> add your user, then sign out/in Defensive patterns
Strategy: fallback
Validate before calling
// Probe writability of the runtime dir before relying on the agent symlink
use std::os::unix::fs::symlink;
fn runtime_dir_linkable() -> bool {
let probe = config::RUNTIME_DIR.join(".link-probe");
symlink("/nonexistent-target", &probe).is_ok() || {
let ok = probe.exists();
let _ = std::fs::remove_file(&probe);
ok || probe.symlink_metadata().is_ok()
}
} Try / catch
// Note: the initial-symlink failure is already only logged by AgentProxy::new();
// downstream, treat a missing agent.<PID> link as degraded (no agent forwarding)
// rather than fatal:
if !sock_path.symlink_metadata().is_ok() {
log::warn!("ssh agent proxy unavailable; SSH_AUTH_SOCK passthrough degraded");
} Prevention
- On Windows, enable Developer Mode or grant the 'Create symbolic links' user right
- Keep the wezterm runtime dir user-writable (check XDG_RUNTIME_DIR ownership)
- Clear stale agent.<PID> files after crashes so the remove-and-relink path stays clean
When it happens
Trigger: Running wezterm on Windows as a user without the SeCreateSymbolicLinkPrivilege; RUNTIME_DIR not writable (root-owned, full disk, sandboxed home); security software blocking symlink creation; the target SSH_AUTH_SOCK path being on a filesystem that rejects links.
Common situations: Fresh Windows box where Developer Mode / the symlink privilege was never enabled; XDG_RUNTIME_DIR pointing at a directory with wrong ownership after a UID change; containers with read-only /run.
Related errors
- {} is not a file
- {} is not a file
- window_id {} not found on this server
- window {} has no tabs
- pane {} wasn't in its containing tab!?
AI-assisted analysis of wezterm/wezterm@9c04f79f86 (2026-08-16).
Data as JSON: /api/errors/e95c7c8f840aeaee.
Report an issue: GitHub.