{"record":{"id":"e95c7c8f840aeaee","repo":"wezterm/wezterm","slug":"failed-to-create-symlink-err","errorCode":null,"errorMessage":"failed to create symlink {} -> {}: {err:#}","messagePattern":"failed to create symlink (.+?) -> (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"mux/src/ssh_agent.rs","lineNumber":72,"sourceCode":"fn update_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> anyhow::Result<()> {\n    let original = original.as_ref();\n    let link = link.as_ref();\n\n    match symlink_file(original, link) {\n        Ok(()) => Ok(()),\n        Err(err) => {\n            if err.kind() == std::io::ErrorKind::AlreadyExists {\n                std::fs::remove_file(link)\n                    .with_context(|| format!(\"failed to remove {}\", link.display()))?;\n                symlink_file(original, link).with_context(|| {\n                    format!(\n                        \"failed to create symlink {} -> {}: {err:#}\",\n                        link.display(),\n                        original.display()\n                    )\n                })\n            } else {\n                anyhow::bail!(\n                    \"failed to create symlink {} -> {}: {err:#}\",\n                    link.display(),\n                    original.display()\n                );\n            }\n        }\n    }\n}\n\nimpl AgentProxy {\n    pub fn new() -> Self {\n        let pid = unsafe { libc::getpid() };\n        let sock_path = config::RUNTIME_DIR.join(format!(\"agent.{pid}\"));\n\n        if let Some(inherited) = Self::default_ssh_auth_sock() {\n            if let Err(err) = update_symlink(&inherited, &sock_path) {\n                log::error!(\"failed to set {sock_path:?} to initial inherited SSH_AUTH_SOCK value of {inherited:?}: {err:#}\");\n            }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/wezterm/wezterm/blob/9c04f79f86649f76a8c978ff4b674f60297a6ec9/mux/src/ssh_agent.rs#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before: unprivileged Windows user\n> wezterm.exe   # log: failed to create symlink ... agent.<PID>\n\n# after: grant the right (admin shell)\n> secpol.msc  # Local Policies -> User Rights Assignment ->\n              # 'Create symbolic links' -> add your user, then sign out/in","handlingStrategy":"fallback","validationCode":"// Probe writability of the runtime dir before relying on the agent symlink\nuse std::os::unix::fs::symlink;\nfn runtime_dir_linkable() -> bool {\n    let probe = config::RUNTIME_DIR.join(\".link-probe\");\n    symlink(\"/nonexistent-target\", &probe).is_ok() || {\n        let ok = probe.exists();\n        let _ = std::fs::remove_file(&probe);\n        ok || probe.symlink_metadata().is_ok()\n    }\n}","typeGuard":null,"tryCatchPattern":"// Note: the initial-symlink failure is already only logged by AgentProxy::new();\n// downstream, treat a missing agent.<PID> link as degraded (no agent forwarding)\n// rather than fatal:\nif !sock_path.symlink_metadata().is_ok() {\n    log::warn!(\"ssh agent proxy unavailable; SSH_AUTH_SOCK passthrough degraded\");\n}","preventionTips":["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"],"tags":["ssh-agent","symlink","filesystem","permissions","windows","rust","wezterm"],"backgroundTag":"symlink-creation-failed","analyzedSha":"9c04f79f86649f76a8c978ff4b674f60297a6ec9","analyzedAt":"2026-08-16T21:23:27.157Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}