{"record":{"id":"88fa4432d999eb2c","repo":"shadowsocks/shadowsocks-rust","slug":"user-not-found","errorCode":null,"errorMessage":"user {} not found","messagePattern":"user (.+?) not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/sys.rs","lineNumber":104,"sourceCode":"\n    unsafe {\n        let pwd = match uname.parse::<libc::uid_t>() {\n            Ok(uid) => {\n                let mut pwd = libc::getpwuid(uid);\n                if pwd.is_null() {\n                    let uname = CString::new(uname).expect(\"username\");\n                    pwd = libc::getpwnam(uname.as_ptr())\n                }\n                pwd\n            }\n            Err(..) => {\n                let uname = CString::new(uname).expect(\"username\");\n                libc::getpwnam(uname.as_ptr())\n            }\n        };\n\n        if pwd.is_null() {\n            return Err(Error::new(ErrorKind::InvalidInput, format!(\"user {} not found\", uname)));\n        }\n\n        let pwd = &*pwd;\n\n        // setgid first, because we may not allowed to do it anymore after setuid\n        if libc::setgid(pwd.pw_gid as libc::gid_t) != 0 {\n            let err = Error::last_os_error();\n\n            error!(\n                \"could not change group id to user {:?}'s gid: {}, uid: {}, error: {}\",\n                CStr::from_ptr(pwd.pw_name),\n                pwd.pw_gid,\n                pwd.pw_uid,\n                err\n            );\n            return Err(err);\n        }\n","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/src/sys.rs#L86-L122","documentation":"When the daemon is told to run as a different user (run_as_user / -u option), it looks up the username with libc::getpwnam. If the lookup returns NULL the user does not exist on this system, so it returns ErrorKind::InvalidInput with \"user <name> not found\". Privilege-dropping then fails and startup aborts.","triggerScenarios":"Starting the daemon with -u <username> (or equivalent config) where the username has no passwd entry — typo in username, user exists only in LDAP/AD not in local passwd, or running in a minimal container (e.g. scratch/distroless) without the user defined.","commonSituations":"Docker containers built without `useradd`/passwd entry; systemd unit User= mismatch after image change; k8s securityContext runAsUser combined with -u name that doesn't exist inside the image; NIS/LDAP user not resolvable at startup.","solutions":["Create the user before starting: `useradd -r -s /usr/sbin/nologin shadowsocks` in the image/host","Fix the username typo in the -u flag or config file","If using central directory (LDAP/AD), ensure NSS is configured so getpwnam resolves that user","Alternatively use a numeric UID where supported, or run as root without -u (not recommended)"],"exampleFix":"# before (Dockerfile)\nCMD [\"sslocal\", \"-u\", \"nobodyx\", ...]\n# after\nRUN useradd -r -s /usr/sbin/nologin shadowsocks\nCMD [\"sslocal\", \"-u\", \"shadowsocks\", ...]","handlingStrategy":"validation","validationCode":"// Before launching with -u, verify the user resolves via getpwnam\nfn user_exists(name: &str) -> bool {\n    match std::ffi::CString::new(name) {\n        Ok(c) => unsafe { !libc::getpwnam(c.as_ptr()).is_null() },\n        Err(_) => false,\n    }\n}\nassert!(user_exists(\"shadowsocks\"), \"user 'shadowsocks' missing — create it before starting the daemon\");","typeGuard":null,"tryCatchPattern":"match daemon::run_as_user(\"shadowsocks\") {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains(\"not found\") => {\n        eprintln!(\"run-as user missing on host; aborting instead of running as root\");\n        std::process::exit(1);\n    }\n    r => r,\n}","preventionTips":["Create the service user in Dockerfiles/AMIs before the entrypoint runs","Verify the user exists inside the container image (scratch/distroless images lack passwd entries)","Prefer numeric UIDs in k8s securityContext and avoid -u in containers when the user is external","Test the full startup path in the target environment, not just on the dev machine"],"tags":["unix","privilege-drop","user","configuration","container"],"backgroundTag":"user-not-found","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}