Skip to content

native: detect libc via process.report, not ldd#2

Merged
Jeff Lubetkin (jefflub-ashby) merged 1 commit into
napi-jemallocfrom
fix/native-libc-detection
Jun 30, 2026
Merged

native: detect libc via process.report, not ldd#2
Jeff Lubetkin (jefflub-ashby) merged 1 commit into
napi-jemallocfrom
fix/native-libc-detection

Conversation

@jefflub-ashby

Copy link
Copy Markdown

Problem

isMusl() shells out to ldd --version and treats any failure as musl:

try {
  const ldd = execSync("ldd --version 2>&1", ...);
  return ldd.includes("musl");
} catch {
  return true; // <-- assumes musl on failure
}

Minimal runtime images (Google distroless, scratch) ship no ldd binary, so the execSync throws → the loader concludes musl on a glibc host → it builds platformKey = "linux-x64-musl", for which no prebuild/platform package exists, and fails at startup:

Native addon not found for linux-x64-musl. Install
@ashbyhq/libpg-query-native-linux-x64-musl or ensure it's in your dependencies.

This bit a real deploy onto gcr.io/distroless/nodejs24-debian13 (glibc, glibcVersionRuntime: 2.41) — the correct linux-x64 binary was present but never selected.

Fix

Detect libc using Node's own process.report.header.glibcVersionRuntime (set on glibc, absent on musl) — no subprocess, so it works in minimal images. Falls back to probing /lib/ld-musl-* on older runtimes without process.report, and defaults to glibc (the common case) when uncertain.

Verification

  • gcr.io/distroless/nodejs24-debian13:nonroot (glibc): isMusl()false; loader selects linux-x64 and parses (version: 180004). ✅
  • node:24-alpine (musl): isMusl()true. ✅

Bumps the package to 0.1.1.

🤖 Generated with Claude Code

isMusl() shelled out to `ldd --version` and treated any failure as musl.
Minimal images (distroless/scratch) ship no `ldd`, so the call throws and
a glibc host is misdetected as musl — selecting a platform package/prebuild
that doesn't exist and failing at load with "Native addon not found for
linux-x64-musl".

Use Node's process.report.header.glibcVersionRuntime (set on glibc, absent
on musl), with a /lib/ld-musl-* fallback and a glibc default. Verified:
distroless debian13 now resolves linux-x64; node:alpine still resolves musl.
Bump to 0.1.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jefflub-ashby Jeff Lubetkin (jefflub-ashby) merged commit b5ce5b5 into napi-jemalloc Jun 30, 2026
38 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant