neon-bindings/neon · error
Failed to find N-API version
Error message
Failed to find N-API version
What it means
During symbol loading, `napi_get_version` was resolved from the host library via libloading, but the call either failed to load the symbol or did not return Status::Ok, so the Node-API version reported by the running Node process could not be determined. This indicates the module is not running inside a Node-API-capable host (e.g. loaded by a non-Node process) or a broken libloading resolution.
Solutions
- Run the module under a Node.js version that supports Node-API (napi_get_version is available since Node 10+ / all N-API-capable releases)
- Do not load the .node addon via dlopen/LoadLibrary from non-Node host processes
- On Windows, ensure the module is loaded through the normal require() path so Library::this() resolves the host correctly
- Check `Error: Module did not self-register` cases — the module may have been linked against a host without N-API
Example fix
Load the addon with a supported Node.js runtime (Node >= the version matching the crate's napi feature); do not dlopen the .node addon from non-Node processes.
Defensive patterns
Strategy: fallback
Prevention
- Declare and test against a minimum Node.js version in CI
- Pin the napi-* feature of neon to match the oldest Node version you support
When it happens
Trigger: `load` runs when the native module is registered; it panics if `get_version` cannot resolve `napi_get_version` from the host process or the call returns a status other than Status::Ok — i.e. the host has no Node-API support.
Common situations: Native module loaded outside of Node.js (e.g. from another FFI host); a Node binary so old it lacks N-API; corrupted/incompatible libloading setup on Windows where `Library::this()` itself fails.
AI-assisted analysis of neon-bindings/neon@38960e4381 (2026-09-13).
Data as JSON: /api/errors/49b3eda20a51175c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/neon/src/sys/bindings/functions.rs:458
// This symbol is loaded separately because it is a prerequisite
unsafe fn get_version(host: &libloading::Library, env: Env) -> Result<u32, libloading::Error> {
let get_version = host.get::<fn(Env, *mut u32) -> Status>(b"napi_get_version")?;
let mut version = 0;
assert_eq!(get_version(env, &mut version as *mut _), Status::Ok,);
Ok(version)
}
pub(crate) unsafe fn load(env: Env) -> Result<(), libloading::Error> {
#[cfg(not(windows))]
let host = libloading::os::unix::Library::this().into();
#[cfg(windows)]
let host = libloading::os::windows::Library::this()?.into();
// This never fail since `get_version` is in N-API Version 1 and the module will fail
// with `Error: Module did not self-register` if N-API does not exist.
let actual_version = get_version(&host, env).expect("Failed to find N-API version");
let expected_version = match () {
_ if cfg!(feature = "napi-8") => 8,
_ if cfg!(feature = "napi-7") => 7,
_ if cfg!(feature = "napi-6") => 6,
_ if cfg!(feature = "napi-5") => 5,
_ if cfg!(feature = "napi-4") => 4,
_ if cfg!(feature = "napi-3") => 3,
_ if cfg!(feature = "napi-2") => 2,
_ => 1,
};View on GitHub (pinned to 38960e4381)