#Images processed by Astro image service throw a 500 Internal Server Error in production

88 messages · Page 1 of 1 (latest)

craggy violet
#

Hey all! I suddenly found images rendered with the astro:assets <Image> component are failing to load when I deploy my application to production. This only started happening over the past few days. Images have worked as expected for over a year. I am running the latest Astro 5.14.5 and have not recently changed my image config in astro.config.mjs:

  image: {
    domains: ["soapbox.host"],
    remotePatterns: [
      {
        protocol: "https",
      },
    ],
  },

These images load as expected when running locally. No error is logged to the console in production. The images just silently fail to load with a 500 error.

Examples of 500 error:
https://soapbox.host/_image?href=%2F_astro%2Fsoapbox-wordmark-white.B2nHWaBM.svg&w=110&h=28&f=svg
https://soapbox.host/_image?href=%2F_astro%2Fmanage_episodes_screenshot_new.Df0vBHVg.webp&w=1359&h=938&f=webp

Is there a way to further debug what is going on here? A way to enable verbose logging for the image service maybe?

#

If it helps, I deploy to a VPS using dokku which builds the Astro site in a Docker container.

#

I thought it could be related to the default sharp service but I just confirmed it also happens with the passthrough image service.

ancient anvil
#

Hi! If you roll back to an earlier Astro version, does this still happen?

#

For example, 5.13.0?

craggy violet
#

I'll try now, thanks for the suggestion!

ancient anvil
#

Also, very cool project. Love people improving the Podcast Ecosystem :D

craggy violet
#

Thanks!!! I've been working on it for 2 years and am finally ready to launch it publicly. And then images broke ablobcry

ancient anvil
#

Also, another point of reference. Is this only happening on your VPS? Or does this also happen if you try to run Astro locally with the preview command?

craggy violet
#

Haven't tried preview but have tried running locally with the same build and run command as prod. Will try preview now.

#

Unable get to the same 500 error running locally with astro preview. Downgrade is going live now so will be able to check that shortly.

ancient anvil
#

I wonder if that's got something to do with your Docker environment then. Does it show warnings or errors in your build logs?

craggy violet
#

(Which do work.)

#

I don't understand why the error would not be logged anywhere though, I'd expect the 500 response code to also log the error to the console, no?

ancient anvil
#

Yeah same

#

And the downgrade didn't fix it either?

craggy violet
#

Will be live in <60 seconds and will check

ancient anvil
#

Aight, take your time!

craggy violet
#

I wonder if I can take a look at the Astro source code for the image processing and see under what circumstances it returns a 500?

ancient anvil
#

I guess so yeah

#

I'm not familiar with Dokku, how is the container built?

#

What image does it run in etc.?

ancient anvil
#

Could you maybe share how you're using the <Image /> component for one of your local images?

craggy violet
#
---
import soapboxWordmarkWhite from "assets/soapbox-wordmark-white.svg";
___

<Image src={soapboxWordmarkWhite} height={64} alt="Soapbox" />

With the tsconfig setup to allow importing from "assets/" instead of src/assets

ancient anvil
#

I think the behaviour for that changed in Astro 5.7. SVGs are now considered components, so you can theoretically use them like this:

---
import SoapboxWordmarkWhite from "assets/soapbox-wordmark-white.svg";
___

<SoapboxWordmarkWhite height={64} />
Docs

Learn how to use images in Astro.

#

I think there was a way to use them with the Image component as well, but that might've changed too

craggy violet
ancient anvil
#

Then nevermind that kek
I'll keep digging.

#

The same definitely works for my sites, and I don't do anything much different. Same usage in the code as well.

#

Are you using the @astrojs/node adapter btw? If not that's fine, just curious

craggy violet
#

Yes, in standalone mode

#

and the whole Astro site in server output

ancient anvil
#

And what docker image is this running on again?

#

Just standard node? If so, which version?

craggy violet
#

Hmm, I'm not sure as it automatically picks up that it's a NodeJS app and installs the specific Node version, pnpm version, and dependencies. I'll see if I can get exact details

#

If it helps, it started happening on Node v22 though I upgrade to v24 just to see if it helped and no change. So currently on 24.10.0

#

I have to run now but I will return later to keep searching. I seriously appreciate your time! I'm going to look closer at the source code you found and try to back trace exactly what's happening from there.

ancient anvil
#

Yep. Pretty much the conclusion I came to

#

I'm wondering if it's loading node-alpine or some version/runtime where node:fs/promises just doesn't work as intended? It's very weird

#

We know the image exists after all

craggy violet
#

Looks like importing the .svg files and using them directly as components gets around this issue. So I will switch over all the svgs to that for now, and that mostly unblocks me. Thanks for pointing that out!

craggy violet
#

I'm able to reproduce the Internal Server Error locally if I manually delete the SVG files from my dist/client/_astro folder that is created by astro build, further confirming it's an issue reading the local file...

hard ice
#

Just noticed that our business website is throwing 'Internal Server Errors' for all images too, I run Astro in SSR mode with images in the 'assets' directory.

#

Thought maybe 1 of the debian updates I installed was causing the issue, thought maybe I screwed something up in my lighttpd reverse-proxy setup, then decided to search here.

primal gyro
#

There was a breaking change in a patch around images recently because of a CVE, review the github releases carefully

hard ice
#

Can't see one relating to images specifically? The image loading only stopped working a few days ago when I updated the site. (Exactly 3 days ago according to my webserver logs, which makes sense, since that's when I updated Astro).

#

Found it, but that was, from what I can see, 5.13.2, and I've been running 5.14.1 for 3 weeks, and prior to that 5.13.3, all from what I can tell, with no issues.

#

None of my images are using a // or data or anything that would consider them to be remote, I have an 'assets' directory inside of /src, and I use the '<Image>' component to render them.

craggy violet
#

Yep, sounds just like my issue.

hard ice
#

Switching our main logo to SVG fixed the problem, but that won't work for our other images, most of which are sent to us by our suppliers.

#

I think the more annoying issue is that I can't test it in development, because all images work 100%. 'npm run dev' has the images showing perfectly, 'npm run build' and the images all break.

mild jetty
#

Hi, I'm currently facing the same issue :/ did anyone of you fix it ?

mild jetty
#

reverrting back to 5.13.0 seems to fix the issue :/

craggy violet
craggy violet
#

The path it comes up with "/tmp/build" is wrong.

craggy violet
#

It looks like it built the url at the time of building, when it was being built in /tmp/build, but then the app is deploy in /app and the path is no longer valid.

craggy violet
#

Yep, so it uses the build output directory, which may or may not be the final location of the built files. So this impacts users whose deployment includes moving files after they are built. I imagine this is pretty common.

I have a temporary fix locally applied that replaces "/tmp/build" with "/app" which is the proper path for my case.

#

It works!

hard ice
#

I have a gitea action so that when I commit, it fetches the changes on my dev system then restarts using 'pm2 restart 0'. When I'm ready to deploy, I manually run 'npm run build', then scp the contents of dist/* over to my production server, then manually run pm2 restart 0.

#

I tried to automate that part, but it never worked for me, and this has all been going fine until that bad release.

primal gyro
#

I may have missed it but did you manage to isolate the exact patch were things went wrong?

hard ice
#

5.13.3 I think it is

primal gyro
hard ice
#

Oops, meant 5.13.2, sorry

#

This particular change in 5.13.2: 4d16de7 Thanks @smoky heart! - Improves the detection of remote paths in the _image endpoint. Now href parameters that start with // are considered remote paths.

#

I think somehow that 1 change may have fixed remote paths but broken local paths

craggy violet
#

Trying to think about what a solution would look like here. Would it require a new config option alongside the build output directory that specifies the deployment directory for cases like this where they differ?

smoky heart
#

We usually don't recommend this kind of setup because we rely on the file system paths after the build

#

By chance, you were leveraging the bug that was fixed. Not sure how to fix this use case though

hard ice
#

It sounds like a few of us (possibly a lot, I don't know), are utilising this. And in my case, it isn't going to be easy to revert back to some other way to do it. I mean, I'm not going to copy across the entire directory structure, because I simply do not trust nodes ability to keep anything outside of 'dist' safe.

#

Which means all I want copied across to the production server is the contents of 'dist'

#

Not to mention it still works fine for SVG files that are locally hosted, just not png, jpg, etc...

#

The other issue is that out of all the deployment guides, self-hosted / nodejs is not one of them, so naturally people are just going to revert back to how they have always deployed websites between dev and prod, which could end up as completely different directory structures.

smoky heart
#

It would be great to have a minimal reproduction attached to the issue, so we can move from there

hard ice
#

I would love to, I'm just not sure how to make that work. And the guide didn't really assist me in any way at all either 🙁

craggy violet
#

I can work on a minimal reproduction. All it would be is building and then moving the built folder to a new directory.

A short term improvement would be to remove the try {} catch {} block that results in the error being ignored, I can open a PR for that

craggy violet
primal gyro
craggy violet
hard ice
#

What's the non-pnpm way?