Skip to content
Nilay Kabariya

Entry No.090·Fixes·Updated ·4 min read

Node 26 error: libatomic.so.1 cannot open shared object file

node or npm fails with error while loading shared libraries: libatomic.so.1 after moving to Node 26. Tested on 9 Linux images, Docker and nvm, with fixes.

by Nilay#node#linux#dockerFIXED

The error, verbatim

Jump to the fix ↓
node: error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory

Tested on

Node
26.12.1 and 24.22.1 (official Linux binaries, x64 and arm64)
Images
Debian 12 and 13, Ubuntu 22.04 and 24.04, Amazon Linux 2023, Fedora 42, Rocky 9, UBI 9, openSUSE Leap 15.6
Also
nvm 0.40.3, Docker multi-stage, distroless/cc-debian12
Runner
GitHub Actions ubuntu-latest and ubuntu-24.04-arm
Contents
  1. Which systems fail01
  2. Why npm shows the same error02
  3. The fix: install libatomic03
  4. In Docker: copying node into a slim image04
  5. nvm says it worked, then node fails05
  6. Systems that weren’t affected06
  7. How this was tested07

Node 26 became the LTS release on October 28, 2026 (26.13.0), so this is the week a lot of servers, CI jobs and Docker images move to it from Node 24. On a minimal Linux system, the first thing many of them will print is:

node: error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory

Nothing is wrong with your code or your Node download. Since Node 25, the official Linux binaries need one more system library, libatomic, and many minimal systems don’t have it. The Node 26 LTS release notes say so in one sentence: the binaries are “linked against libatomic, which may need to be installed separately depending on your Linux distribution”.

I checked the binaries themselves. readelf -d lists libatomic.so.1 as a dependency of node 26.12.1, on both x64 and arm64. It isn’t in the list for node 24.22.1. The LTS release, 26.13.0, lists it too.

Which systems fail

I unpacked the official node-v26.12.1-linux-x64 and node-v24.22.1-linux-x64 tarballs and ran each one in clean Docker images, with nothing installed first:

Image libatomic before Node 26 Node 24
debian:bookworm-slim (Debian 12) missing fails works
debian:trixie-slim (Debian 13) missing fails works
ubuntu:24.04 missing fails works
ubuntu:22.04 missing fails works
amazonlinux:2023 missing fails works
fedora:42 missing fails works
rockylinux:9-minimal missing fails works
redhat/ubi9-minimal missing fails works
opensuse/leap:15.6 missing fails works
node:26-bookworm-slim (official image) present works works

Every plain base image failed, and every one ran Node 24 without complaint. The official node:26 image is fine because it ships the library. The arm64 binary failed the same way in debian:bookworm-slim on an arm64 runner.

In CI, this usually shows up as exit code 127, the same code a missing command gives, which makes it easy to misread as “node isn’t installed”.

Why npm shows the same error

Running npm -v gave a shorter version of the error:

node: error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory

npm is a script that starts node, so it’s node that fails, and npm never runs. Fixing node fixed npm too.

The fix: install libatomic

Install the distro’s libatomic package:

Distro Command
Debian, Ubuntu apt-get install -y libatomic1
Amazon Linux 2023, Fedora dnf install -y libatomic
Rocky, RHEL UBI (minimal images) microdnf install -y libatomic
openSUSE zypper install -y libatomic1

On Debian and Ubuntu, run apt-get update first in a fresh container.

In Docker: copying node into a slim image

A common way to hit this is a multi-stage Dockerfile that copies only the node binary out of the official image into a smaller base:

FROM node:26-bookworm-slim AS n
FROM debian:bookworm-slim
COPY --from=n /usr/local/bin/node /usr/local/bin/node

This worked with node:24. With node:26, the container failed on start with the libatomic.so.1 error, because the binary came across without the library. gcr.io/distroless/cc-debian12 failed the same way.

Copy the library from the same stage, or install it in the final image:

FROM node:26-bookworm-slim AS n
FROM debian:bookworm-slim
COPY --from=n /usr/local/bin/node /usr/local/bin/node
COPY --from=n /usr/lib/x86_64-linux-gnu/libatomic.so.1 /usr/lib/x86_64-linux-gnu/

On arm64, the path is /usr/lib/aarch64-linux-gnu/. On a Debian-based final image, RUN apt-get update && apt-get install -y --no-install-recommends libatomic1 works too.

On October 28, there was no gcr.io/distroless/nodejs26-debian12 image yet; pulling it returned not found.

nvm says it worked, then node fails

With nvm 0.40.3 in debian:bookworm-slim, nvm install 26 downloaded Node, matched the checksum and printed Now using node v26.12.1, with exit code 0. The very next node -v failed with the libatomic.so.1 error. nvm installs the same official binary, and it doesn’t check whether that binary can start.

The fix is the same package. After apt-get install -y libatomic1, the Node that nvm installed ran without reinstalling it.

Systems that weren’t affected

  • The official node:26 Docker images. node:26-bookworm-slim already contains libatomic.so.1.
  • GitHub-hosted runners. ubuntu-latest already has libatomic.so.1 installed, so actions/setup-node on the runner itself is fine. Only containers and self-hosted machines built from minimal images are at risk.
  • Alpine is a separate problem. In node:26-alpine, the official glibc tarball didn’t run at all (not found), for Node 24 as well. That’s the musl vs glibc split, not libatomic. Use the node:26-alpine image’s own node instead.

How this was tested

October 28, 2026, on GitHub Actions: ubuntu-latest (x64) and ubuntu-24.04-arm (arm64) runners with Docker. The official Node 26.12.1 and 24.22.1 Linux tarballs were downloaded from nodejs.org and mounted into each image without installing anything first. Each image then got its distro’s libatomic package, and the same binaries ran again. The Docker cases built real multi-stage images. Node 26.13.0, the LTS release itself, changes only release metadata after 26.12.1, according to its release notes, and its binary lists libatomic.so.1 too (checked October 29). The scripts and the full output are public.

— N.K., end of entry No.090

Useful? Pass it on:Post on XFollow @EmotionalMatter

Related entries

  1. No.057

    Node 26 vs Node 24: what breaks when you upgrade, tested

    Most projects move over cleanly: jsonwebtoken, bcrypt, sharp, better-sqlite3 13, tsx and Vitest all worked unchanged. What broke: Corepack and Yarn are gone (Docker builds fail with exit code 127), native modules installed under Node 24 refuse to load, fs.rmdir with recursive now throws (prisma generate with zod-prisma-types fails on the second run), and fs.W_OK disappeared without an error.

    TESTED8 minWindows
  2. No.093

    Fix: bigint Failed to load bindings, pure JS will be used

    bigint: Failed to load bindings, pure JS will be used. Why npm 12 shows it on every install, whether it matters, and how to get the native build back.

    > bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)

    FIXED3 minWindows
  3. No.086

    npm error code EACCES: permission denied, 3 causes tested

    npm error code EACCES with syscall mkdir or open: a global install, a cache that sudo left behind, or Docker. Each reproduced, with the fix that lasts.

    > npm error code EACCES

    FIXED2 min

Post card · Every Sunday

What broke this week.

One email on Sundays: the Node, TypeScript, Python and AI SDK releases that broke builds that week, each one reproduced, with a link to the fix that worked. Never shared, and you can leave any time.

— Nilay

or follow by RSSor on X

By subscribing you agree to the privacy note. One click to leave.

tip: paste the exact error text