nuxt/image 500 errors using ipx provider
i use @nuxt/image 1.11.0 with the ipx provider.
I use local images from my /public folder as well as images from a remote site.
I added the doamin to the config.
Local builds are running fine.
As soon as i move the build (generate) process to a github runner, nuxt/image throws 500 errors (for local and remote images).
8 Replies
Hi @Single. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
It sounds like your GitHub runner build is missing the Sharp binary that IPX relies on at runtime. The default ipx/ipxStatic provider in @nuxt/image uses unjs/ipx, which depends on sharp. If sharp isn’t compiled for the target environment (or is stripped during build), IPX requests return 500 (IPX_ERROR) when your app runs. This often works locally but fails in CI or on servers. [IPX]
Evidence and fixes from the sources:
- The exact 500 IPX_ERROR with “Something went wrong installing the sharp module … Cannot find module '../build/Release/sharp-linux-x64.node'” is a known failure mode. The recommended fix is to install/rebuild sharp for the target runtime/arch in CI (e.g., linux x64). [SO: 500 IPX_ERROR]
- One user resolved it by rebuilding sharp for Linux/musl in their production build step: npm rebuild --arch=x64 --platform=linux --libc=musl sharp (adjust libc to your runner image, e.g., glibc vs musl). [SO: Part 3]
Checklist to fix:
1) Ensure sharp is present and built for the runner’s environment
- Add sharp as a dependency/devDependency in your project and rebuild it in CI after install:
- If using Ubuntu (glibc), try: npm rebuild --arch=x64 --platform=linux sharp
- If using Alpine/musl (common in containers), use: npm rebuild --arch=x64 --platform=linux --libc=musl sharp
Run this in the same environment that runs the app. [SO: 500 IPX_ERROR; SO: Part 3]
2) Verify image locations and config
- With the default ipx provider, local images should come from public/. If your sources are in assets/, either move them to public/ or set image.dir accordingly. [Providers; dir]
- For remote images, ensure the remote domain(s) are added to image.domains. [Providers]
3) If generating a static site
- The default provider switches to ipxStatic with static nitro presets (e.g., nuxt generate). If you disabled SSR, prerender IPX URLs you need or you’ll see 404/500 for dynamic variants not generated. [provider; Static images]
4) If you’re deploying to a platform with a native image CDN
- Consider using the platform provider (e.g., Netlify) instead of ipx, which avoids bundling sharp. You can set provider: 'netlify' when deploying there. [Netlify]
Quick CI example step (Ubuntu runner):
- After npm ci:
- npm rebuild --arch=x64 --platform=linux sharp
- Then nuxt build or nuxt generate. [SO: 500 IPX_ERROR; SO: Part 3]
If you share your runner OS (Ubuntu vs Alpine), and whether you deploy the .output server to a different environment than the runner, I can suggest the exact rebuild command and where it should run.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
<@176706136232296449> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai rebuilding sharp did the trick. Why is this needed?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Because the IPX provider uses Sharp under the hood, and Sharp ships platform-specific native binaries. When you build/run on a different environment than where dependencies were originally installed (e.g., local macOS vs Linux GitHub runner, or glibc vs musl), the prebuilt Sharp binary doesn’t match the target runtime. At runtime, IPX tries to load Sharp and fails with “Cannot find module … sharp-linux-x64.node,” causing 500 IPX_ERROR responses. Rebuilding Sharp in the CI/target environment compiles or fetches the correct native binary for that OS/arch/libc, so IPX can work. [IPX; SO: 500 IPX_ERROR; SO: Part 3]
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
<@176706136232296449> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai i couldnt see any errors. Pnpm prepare should install the actual sharp binary for the current (active) os and arch, no?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Short answer: not always.
What happens is tied to when and where sharp’s native binary is resolved:
- IPX (the default Nuxt Image provider) relies on sharp at runtime. If the installed sharp binary doesn’t match the OS/arch/libc that will actually execute your app, IPX fails with a 500 and a sharp “native binding” error. [IPX; SO 500 IPX_ERROR]
- In CI/deploys, the environment that runs nuxt prepare/postinstall (which installs native deps) may differ from the environment that later runs your built app (e.g., macOS dev → Linux runner; glibc Ubuntu → musl Alpine container). In those cases, the prebuilt binary sharp picked up during install won’t match the final runtime, and you’ll hit the error unless you rebuild sharp for the target environment. This is why running a targeted rebuild (e.g., npm rebuild --arch=x64 --platform=linux [--libc=musl] sharp) fixes it. [SO Part 1; SO Part 3]
- The Nuxt Image docs explicitly note sharp/node-gyp issues can occur depending on OS/Node, and recommend rebuilding/ensuring correct binaries if prebuilt ones aren’t available for your platform. [Installation]
So, even if pnpm (or npm) runs nuxt prepare and installs sharp, that install only guarantees binaries for the environment where it ran. If your final runtime differs, you need to rebuild sharp in that target environment (or ensure your build and runtime environments match). [Installation; SO 500 IPX_ERROR]
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
<@176706136232296449> Kapa.ai is still learning and improving, please let me know how I did by reacting below.