Part of Hosting by frameworkHosting · Troubleshooting

“Could not load the sharp module”: the Linux binary never got installed.

Since version 0.33, sharp keeps its native code in separate per-platform packages such as @img/sharp-linux-x64, installed as optional dependencies. The error means that package isn’t in node_modules on the server. Usually the lockfile was made on macOS or Windows without the Linux entries, or optional dependencies were skipped. Regenerate the lockfile and redeploy.

Facts checked

The exact error

sharp prints the runtime it looked for, then a list of suggestions. On an x64 Linux server it reads like this:

Error: Could not load the "sharp" module using the linux-x64 runtime
Possible solutions:
- Ensure optional dependencies can be installed:
    npm install --include=optional sharp
- Ensure your package manager supports multi-platform installation:
    See https://sharp.pixelplumbing.com/install#cross-platform
- Add platform-specific dependencies:
    npm install --os=linux --cpu=x64 sharp
- Consult the installation documentation:
    See https://sharp.pixelplumbing.com/install

Why the binary goes missing

The sharp package itself ships no prebuilt binary. Its optionalDependencies list one package per platform: @img/sharp-darwin-arm64, @img/sharp-win32-x64, @img/sharp-linux-x64, @img/sharp-libvips-linux-x64 and so on. Each declares the OS and CPU it is built for, and the package manager installs only the ones that match the machine running the install.

So the install on the server has to see the Linux entries in your lockfile, and has to be allowed to install optional dependencies. If either fails, the install still succeeds. The error only appears when code first calls require('sharp'): during the build if the build processes images, otherwise in your app’s logs on the first resize.

The causes, and the fix for each

CauseHow to tellFix
package-lock.json was regenerated on macOS or Windows while node_modules existed, so npm recorded only that machine’s sharp package (npm bug #4828) † †grep '@img/sharp-linux' package-lock.json finds nothingDelete node_modules and package-lock.json, run npm install, commit the new lockfile. Or add the package explicitly: npm install --os=linux --cpu=x64 sharp
Optional dependencies were skipped: --omit=optional, --no-optional, or optional=false in .npmrc †Your install command or .npmrc mentions optionalRemove the flag. sharp’s own message suggests npm install --include=optional sharp
pnpm or Yarn installed only for the current machine and the lockfile or store was shared across platforms †A monorepo or Docker image built on a MacAdd Linux to supportedArchitectures (example below)
node_modules was copied from your machine: a Docker COPY . . without .dockerignore, or a zip that includes node_modules †The server never ran an installExclude node_modules and install on the target. Copying it across platforms causes native-module load errors
sharp 0.32 or older, installed with scripts disabled †npm ls sharp shows 0.32.x or lowerThose versions download libvips and the binary in their install script. Upgrade to sharp 0.33 or later
Node.js is older than sharp supports †The message says Please upgrade Node.js with Found and Requires linessharp 0.35 requires Node 20.9.0 or later. Raise the Node version

† Competitor details come from each vendor’s own published pages on the dates shown; prices and plans change, so check the vendor before you decide. `package-lock.json` was regenerated on macOS or Windows while `node_modules` existed, so npm recorded only that machine’s sharp package (npm bug #4828) (2026-10-29) · `package-lock.json` was regenerated on macOS or Windows while `node_modules` existed, so npm recorded only that machine’s sharp package (npm bug #4828) (2026-10-29) · Optional dependencies were skipped: `--omit=optional`, `--no-optional`, or `optional=false` in `.npmrc` (2026-10-29) · pnpm or Yarn installed only for the current machine and the lockfile or store was shared across platforms (2026-10-29) · `node_modules` was copied from your machine: a Docker `COPY . .` without `.dockerignore`, or a zip that includes `node_modules` (2026-10-29) · sharp 0.32 or older, installed with scripts disabled (2026-10-29) · Node.js is older than sharp supports (2026-10-29)

Check the lockfile before you push

This is the fix for most cases with npm. The Linux packages appear in package-lock.json as node_modules/@img/sharp-linux-x64 and node_modules/@img/sharp-libvips-linux-x64. If a later npm install on your machine drops them again, run the check once more: some npm 11 releases have been reported to bring the bug back.

# 1. Does the lockfile list sharp's Linux packages?
grep -c '"node_modules/@img/sharp-linux-x64"' package-lock.json
grep -c '"node_modules/@img/sharp-libvips-linux-x64"' package-lock.json

# 2. If either prints 0, regenerate the lockfile from scratch
rm -rf node_modules package-lock.json
npm install
grep -c '"node_modules/@img/sharp-linux-x64"' package-lock.json   # should be 1 now

# 3. Commit it
git add package-lock.json
git commit -m "lockfile: include sharp's Linux binaries"

pnpm and Yarn

pnpm and Yarn 3+ read a supportedArchitectures setting that installs optional dependencies for other platforms too. You only need it when one installed tree has to work on two platforms, such as a Docker image built from a Mac’s store. A normal install on the server picks Linux by itself.

# pnpm-workspace.yaml: also install the Linux binaries on a Mac or Windows machine
supportedArchitectures:
  os:
    - current
    - linux
  cpu:
    - current
    - x64

What applies on Canner

  • Installs run on Linux, in the build. Canner runs your package manager’s frozen install (npm ci, pnpm install --frozen-lockfile, and so on) with --ignore-scripts. It does not pass --omit=optional, so the Linux packages install as long as your lockfile lists them.
  • `--ignore-scripts` is not the cause for sharp 0.33 and later. Those versions get their binary from the optional packages, not from an install script (sharp 0.35 has no install script at all).
  • The build-log warning. With sharp in dependencies or devDependencies, the log prints [canner] ⚠ Native modules need a postinstall allowlist (sharp). For a current sharp you can add "canner": { "allowedBuildScripts": ["sharp"] } to package.json to silence it; it does no harm. For pnpm, "pnpm": { "onlyBuiltDependencies": ["sharp"] } works too. With Yarn the allowlist has no effect, because Yarn has no rebuild command.
  • Old sharp won’t work. Canner re-runs allowlisted install scripts with network access blocked, so sharp 0.32’s script can’t download what it needs. Upgrade.
  • Next.js. Next 16 lists sharp as an optional dependency of next, so you don’t have to add it yourself. The lockfile rules above still apply.
  • Where you see it. If your build loads sharp, the error is in the build log. Otherwise it is in the app’s logs on the Logs page, at the first image request. See logs and errors.

Reproduce it locally

A clean Linux container installs exactly what your lockfile says. If sharp ok doesn’t print here, it won’t work on any Linux host:

# Install the way a Linux server does, from a copy so your own node_modules is untouched
docker run --rm -v "$PWD":/src:ro node:22 sh -c \
  "cp -r /src /app && cd /app && rm -rf node_modules \
   && npm ci --ignore-scripts && node -e \"require('sharp'); console.log('sharp ok')\""

Questions

Why does sharp work on my Mac but not on the server?

Your Mac has @img/sharp-darwin-arm64 (or the x64 one) installed; the server needs @img/sharp-linux-x64. If your lockfile only records the Mac package, the server never installs the Linux one.

Will `npm rebuild sharp` fix it?

Not when the platform package is missing. A rebuild runs scripts for packages already installed; it doesn’t add @img/sharp-linux-x64. Fix the lockfile instead.

Do I need to add sharp to allowedBuildScripts on Canner?

Not for sharp 0.33 or later: the binary comes from an optional dependency. Adding it only silences the build-log warning. sharp 0.32 or older needs network access in its install script, which Canner’s rebuild step doesn’t have, so upgrade.

Is there a fallback that doesn’t need a native binary?

sharp can run on WebAssembly through the optional @img/sharp-wasm32 package (npm install sharp @img/sharp-wasm32). It is slower than the native build; use it only on platforms without a prebuilt binary.

Deploy with a build log that names the problem.

Canner warns about native modules before they fail at runtime. The CLI streams the same log to your terminal.