{"record":{"id":"fa4c03b503fe1c44","repo":"shadowsocks/shadowsocks-rust","slug":"launch-socket-with-name-should-be-unique-but","errorCode":null,"errorMessage":"launch socket with name \"{}\" should be unique, but found {}","messagePattern":"launch socket with name \"(.+?)\" should be unique, but found (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/sys/unix/macos.rs","lineNumber":67,"sourceCode":"\n            return Err(err);\n        }\n    }\n\n    let result = if cnt == 0 {\n        Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\"launch socket with name \\\"{}\\\" doesn't exist\", name),\n        ))\n    } else if cnt > 1 {\n        for idx in 0..cnt {\n            unsafe {\n                let fd = *(fds.add(idx));\n                let _ = libc::close(fd);\n            }\n        }\n\n        Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\n                \"launch socket with name \\\"{}\\\" should be unique, but found {}\",\n                name, cnt\n            ),\n        ))\n    } else {\n        // Take fds[0] as the result\n        let fd = unsafe { *fds };\n        Ok(fd as RawFd)\n    };\n\n    if !fds.is_null() {\n        unsafe { libc::free(fds as *mut _) };\n    }\n\n    result\n}","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/sys/unix/macos.rs#L49-L85","documentation":"get_launch_activate_socket expects launchd to check in exactly one file descriptor for the requested socket name. When cnt > 1 (launchd returned multiple fds for that name), it closes all of them and returns InvalidData because it cannot pick one unambiguously.","triggerScenarios":"The launchd plist declares multiple sockets under the same key name (array of listeners) or check-in returns duplicates, while the code requests a single named socket via get_launch_activate_tcp_listener/udp_socket.","commonSituations":"Plist Sockets entry defined as an array of several listeners under one key; copy-pasted duplicate Sockets entries with the same name; combining Bonjour + socket entries collapsing to one name.","solutions":["Ensure each socket in the plist has a unique Sockets key name and request that unique name","If multiple listeners are intentional, retrieve each socket by its own distinct name instead of one shared name","Give the requested socket its own single-entry Sockets dict in the launchd plist"],"exampleFix":"<!-- before -->\n<key>Sockets</key><dict><key>Listener</key><array><dict>..</dict><dict>..</dict></array></dict>\n<!-- after -->\n<key>Sockets</key><dict><key>Listener1</key><dict>..</dict><key>Listener2</key><dict>..</dict></dict>","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match get_launch_activate_socket(name) {\n    Err(e) if e.kind() == io::ErrorKind::InvalidData && e.to_string().contains(\"should be unique\") => {\n        eprintln!(\"plist defines multiple sockets named {name}; use unique names\");\n    }\n    other => other?,\n}","preventionTips":["Use a distinct Sockets key per listener in the launchd plist","Avoid arrays under a single Sockets key when sockets are fetched by name","Audit the plist with `launchctl print` after edits"],"tags":["macos","launchd","socket-activation"],"backgroundTag":"invalid-argument-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}