{"record":{"id":"f690db5bf6bcc6d8","repo":"astrid-runtime/astrid","slug":"fuse-service-control-endpoint-is-already-live","errorCode":null,"errorMessage":"FUSE service control endpoint is already live","messagePattern":"FUSE service control endpoint is already live","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fuse/src/control.rs","lineNumber":126,"sourceCode":"        /// Access class retained by the service.\n        access: StorageProviderAccessV1,\n    },\n    /// Operation completed.\n    Done,\n    /// Service refused the request.\n    Failure {\n        /// Stable local error code.\n        code: String,\n        /// Bounded diagnostic.\n        message: String,\n    },\n}\n\n/// Bind a fresh private control socket, refusing to replace a live service.\npub(crate) fn bind_control_listener(path: &Path) -> Result<tokio::net::UnixListener> {\n    if path.symlink_metadata().is_ok() {\n        if UnixStream::connect(path).is_ok() {\n            bail!(\"FUSE service control endpoint is already live\");\n        }\n        std::fs::remove_file(path).with_context(|| {\n            format!(\n                \"remove stale FUSE service control socket {}\",\n                path.display()\n            )\n        })?;\n    }\n    if let Some(parent) = path.parent() {\n        astrid_core::platform_fs::ensure_private_directory(parent)?;\n    }\n    let listener = StdUnixListener::bind(path)\n        .with_context(|| format!(\"bind FUSE service control socket {}\", path.display()))?;\n    std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o600))?;\n    tokio::net::UnixListener::from_std(listener)\n        .context(\"convert FUSE control listener to the async runtime\")\n}\n","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fuse/src/control.rs#L108-L144","documentation":"bind_control_listener creates a fresh private Unix-socket control endpoint for the FUSE service and refuses to silently replace a live one. If the socket path already exists and a connection succeeds, another service instance is listening, so binding aborts to prevent hijacking an existing service's control channel.","triggerScenarios":"bind_control_listener (called from run_launch) finds that symlink_metadata(path) exists and UnixStream::connect(path) succeeds — meaning a previous/other FUSE service instance is still running and bound to that socket path.","commonSituations":"Starting a second instance of the FUSE service while one is already running; a stale-looking socket that actually still has a live listener; a supervisor restarting the service without stopping the old one first.","solutions":["Stop the already-running FUSE service instance (or its supervisor unit) before relaunching","If no instance should exist, find and kill the leftover process holding the socket","Use a distinct control socket path for the new instance","Only if the connect succeeded spuriously, remove the socket file and retry — the code already removes truly stale (unconnectable) sockets automatically"],"exampleFix":"// before\nrun_launch(\"fuse-service.sock\") // second instance\n// after\nif control_endpoint_live(\"fuse-service.sock\") { stop_existing_instance()?; }\nrun_launch(\"fuse-service.sock\")","handlingStrategy":"try-catch","validationCode":"fn control_endpoint_live(path: &Path) -> bool { path.symlink_metadata().is_ok() && UnixStream::connect(path).is_ok() }","typeGuard":null,"tryCatchPattern":"match run_launch(&opts).await { Err(e) if e.to_string().contains(\"already live\") => { stop_existing_instance()?; run_launch(&opts).await } other => other }","preventionTips":["Run a single service instance per socket path","Use process supervision that stops the old instance before starting a new one","Check for a live listener before launching","Choose unique socket paths per instance"],"tags":["unix-socket","lifecycle","conflict"],"backgroundTag":"address-already-in-use","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}