clash-verge-rev/clash-verge-rev · error · anyhow::Error
effective-user home lookup exceeded the maximum buffer size
Error message
effective-user home lookup exceeded the maximum buffer size
What it means
current_user_home() calls getpwuid_r in a loop, doubling the buffer on each ERANGE return until it exceeds 1 MiB (MAX_BUFFER_SIZE). Bailing past that ceiling stops an unbounded loop: an effective UID whose passwd lookup refuses to fit in a megabyte is treated as broken rather than allowed to grow forever.
Source
Thrown at src-tauri/src/utils/macos_launch_guard.rs:114
std::fs::canonicalize(path).ok()
}
fn current_user_home() -> anyhow::Result<PathBuf> {
const DEFAULT_BUFFER_SIZE: usize = 16 * 1024;
const MAX_BUFFER_SIZE: usize = 1024 * 1024;
let uid = unsafe { libc::geteuid() };
let configured_size = unsafe { libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) };
let mut buffer_size = if configured_size > 0 {
usize::try_from(configured_size).unwrap_or(DEFAULT_BUFFER_SIZE)
} else {
DEFAULT_BUFFER_SIZE
}
.max(1024);
loop {
if buffer_size > MAX_BUFFER_SIZE {
anyhow::bail!("effective-user home lookup exceeded the maximum buffer size");
}
let mut passwd = std::mem::MaybeUninit::<libc::passwd>::zeroed();
let mut result = std::ptr::null_mut();
let mut buffer = vec![0_u8; buffer_size];
let code = unsafe {
libc::getpwuid_r(
uid,
passwd.as_mut_ptr(),
buffer.as_mut_ptr().cast(),
buffer.len(),
&mut result,
)
};
if code == libc::ERANGE {
buffer_size = buffer_size.saturating_mul(2);
continue;
}View on GitHub (pinned to 5cad0f2799)
Solutions
- Run `dscacheutil -q user -a uid <uid>` and `id -p` to inspect what Directory Services returns for the user.
- Flush the directory cache: `dscacheutil -flushcache` then `killall -HUP mDNSResponder`.
- If the Mac is AD-bound, unbind/rebind or fix LDAP reachability to the domain controller.
- As a workaround, set the HOME environment variable and (if patched) the code falls back to it before giving up.
Example fix
// before
if buffer_size > MAX_BUFFER_SIZE {
anyhow::bail!("effective-user home lookup exceeded the maximum buffer size");
}
// after - fall back to $HOME before giving up
if buffer_size > MAX_BUFFER_SIZE {
if let Some(home) = std::env::var_os("HOME") {
return Ok(PathBuf::from(home));
}
anyhow::bail!("effective-user home lookup exceeded the maximum buffer size");
} Defensive patterns
Strategy: fallback
Validate before calling
fn safe_home() -> anyhow::Result<PathBuf> {
match current_user_home() {
Ok(p) => Ok(p),
Err(_) => std::env::var_os("HOME").map(PathBuf::from)
.ok_or_else(|| anyhow::anyhow!("no home directory resolvable")),
}
} Try / catch
let home = match current_user_home() {
Ok(h) => h,
Err(e) => match std::env::var_os("HOME") {
Some(h) if !h.is_empty() => PathBuf::from(h),
_ => return Err(e),
},
}; Prevention
- Keep macOS Directory Service healthy; flush caches when lookups misbehave.
- For embedded/kiosk/CI contexts, set HOME explicitly so the launch guard can fall back.
- Bound the getpwuid_r retry loop (the code already caps at 1 MiB) and always provide an env fallback.
When it happens
Trigger: A misconfigured Directory Service (Open Directory, the AD plugin, or LDAP) returning getpwuid_r=ERANGE indefinitely; libc on a stripped-down macOS sandbox where sysconf(_SC_GETPW_R_SIZE_MAX) reports a wrong size; a corrupted passwd entry with pathological content.
Common situations: macOS bound to a broken AD; containerized/hardened macOS where directory services are restricted; a custom MDM profile that interferes with Open Directory; CI running the launch guard under a synthetic UID.
Related errors
- effective user {uid} has no password database entry
- effective user {uid} has no home directory
- effective user {uid} has an empty home directory
- staged application is not an ordinary bundle directory
- Locales directory not found: ${FRONTEND_LOCALES_DIR}
AI-assisted analysis of clash-verge-rev/clash-verge-rev@5cad0f2799 (2026-08-12).
Data as JSON: /api/errors/ebb93833c514e4f1.
Report an issue: GitHub.