"url" parameter is valid but upstream response is invalid after transitioning to app directory
Unanswered
Bengal posted this in #help-forum
BengalOP
Hey everyone! I have recently transitioned to the app directory and everything worked well locally. However, once I had refactored everything and pushed it to production, every single image that is stored locally has broken. It returns the error "url" parameter is valid but upstream response is invalid. I did some more debugging and refactored the code in the node_modules to throw the actual error, which is an ECONNREFUSED error. The weird part is that images which are loaded externally are actually loading properly (so any image which is not directly from the Next application itself loads perfectly fine, even if it is under a subdomain on the same server).
I'm using:
- Plesk as a hosting environment, which uses Phusion Passenger
- Next 14.0.4, but I tried Next 13 as well
- Node JS 18.19.0, but I tried 20.10.0 and 21.5.0 as well
Does anyone know what could be causing this issue and what I can do to solve it (apart from migrating back to the pages directory again)?
The URL for my website is kwekerijvantuyl.nl.
I'm using:
- Plesk as a hosting environment, which uses Phusion Passenger
- Next 14.0.4, but I tried Next 13 as well
- Node JS 18.19.0, but I tried 20.10.0 and 21.5.0 as well
Does anyone know what could be causing this issue and what I can do to solve it (apart from migrating back to the pages directory again)?
The URL for my website is kwekerijvantuyl.nl.
235 Replies
the image load fine if thw
https://kwekerijvantuyl.nl/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fside_images-2.b52276a8.jpg&w=1200&q=75
w
is 1200https://kwekerijvantuyl.nl/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fside_images-2.b52276a8.jpg&w=1200&q=75
BengalOP
That is a cache error
does Plesk come with cdn cache?
BengalOP
I tried messing with the cache for a bit in order to figure things out, it is actually the wrong Image
It is in the Image cache of Next JS
If you change the quality (q=70) of the image it will break 🙂
Basically what I did is I added a hardcoded cache instance from an image that did work to see if it would then load the remaining images, which it did
Basically, if this function finds a cacheKey it works, because the image has previously loaded. But if it does not find a cacheKey, and thus runs the async function afterwards it'll break
More specifically, this invokeRequest breaks, it returns an ECONNREFUSED error. This error is then translated in Next JS' image optimizer to
"url" parameter is valid but upstream response is invalid
, because it catches the errorBengalOP
I didn't even know that was possible, tried searching for deleting the image cache but didn't find that option yet. I'll do that in a sec!
Perhaps it's also worth to mention that Plesk uses Nginx, I've seen previous posts which had similar issues with Nginx
BengalOP
I changed the caching, but it is still showing the same image. However, I don't think the caching is the main issue here. Something that is also interesting, is that the preloader of the image does actually load the correct images. If you go to another page which has not been cached yet (https://kwekerijvantuyl.nl/overons), you can also see that none of the images are loading. However, for this page it still holds that the preloaders show correctly, as can be seen in the screenshots attached
is it possible to remove the app completely on Plesk and redeploy again?
BengalOP
Yes, but it will not help, as I have this issue with multiple websites
all of those have this issue after updating to app router?
BengalOP
Correct
Could it be that I need to add some nginx directives?
@Bengal Could it be that I need to add some nginx directives?
are you using custom server?
BengalOP
I'm using a dedicated Plesk environment
BengalOP
I tried applying the fix, but it still doesn't work 😦
It might be that the server.js file is not called. I can test that once I'm home
BengalOP
I did some more reading and I previously was not using a custom server, but if it helps with solving the issue I might as well. However, it still does not seem to work. When I add the suggested code, the error message does change into an nginx 504 gateway timeout error, so I don't know if that helps. Also, it is mentioned in the issue that this means that external images will no longer work, while I would still like these to work as I also use and external CMS. Any other suggestions?
A bit earlier I also got the error "url" is invalid (with the same code somehow, probably accidentally changed something unknowingly), so also after adding the server.js fix. This "url" is invalid error was caused because the URL passed to the imageOptimizer was undefined/_next/image?......, I'm assuming this was just some parsing issue or I might have forgotten to add something.
A bit earlier I also got the error "url" is invalid (with the same code somehow, probably accidentally changed something unknowingly), so also after adding the server.js fix. This "url" is invalid error was caused because the URL passed to the imageOptimizer was undefined/_next/image?......, I'm assuming this was just some parsing issue or I might have forgotten to add something.
BengalOP
The images from my CMS work fine
@Ray https://github.com/vercel/next.js/issues/59123#issuecomment-1849458304
yes, i mean the code from this
it have the hostname set to localhost
BengalOP
Why would that help exactly/
ah nm it shouldn't affect it
BengalOP
?*
Alright 😄
I did try setting hostname to my domain name and port to 80, which does not work
Funny enough however, the image does load perfectly fine when I go directly to its source
well I would say try to remove the app completely and redeploy it if possible
BengalOP
Also already tried that :/
oh
same issue?
BengalOP
yupp
oh well
I have no idea then lol
BengalOP
I also have the issue accross different sites, so I'm assuming that it isn't a specific piece of code causing it on my end
Do you know anyone who might have an idea? 🙂
can you access the nginx config?
BengalOP
Yes!
It's my own server, so I can access anything
can you show it?
or do you have
proxy_next_upstream
there?BengalOP
This is what I can see from my panel
I have tried turning Proxy mode off, with no success
Plesk support also suggested the following nginx directives:
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3000;
}
But this just causes the entire website to break lol
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3000;
}
But this just causes the entire website to break lol
can't even access home page?
BengalOP
Nope
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
location / {
proxy_pass http://localhost:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header Host $host;
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
proxy_intercept_errors on;
}
location /_next/image {
proxy_pass http://localhost:3000/_next/image;
}
try this
BengalOP
bad gateway still :/
where do you add it?
BengalOP
Additional nginx directives
what if you just put this?
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
BengalOP
And keep the location /_next/image?
BengalOP
That works, but with the /_next/image it doesn't work
yea I think Additional nginx directives can only add directive
BengalOP
By the way, which server.js should I use?
The default one or the other one?
default one
BengalOP
gotcha
The page is now loading, but still with defect images
I can also add this:
Without any issues, though it still doesn't load the images
location / {
proxy_pass http://localhost:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header Host $host;
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
proxy_intercept_errors on;
}
Without any issues, though it still doesn't load the images
oh really
try adding
location /_next/image {
proxy_pass http://localhost:3000/_next/image;
}
BengalOP
Actually nevermind
I'm stupid
Didn't press apply yet
lol
BengalOP
Or it just hadn't registered yet, either way that doesn't work
@Bengal Plesk support also suggested the following nginx directives:
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3000;
}
But this just causes the entire website to break lol
they asked you to put this block to Additional nginx directives?
BengalOP
Yeah
what do you have in additional nginx directive now?
BengalOP
Currently nothing at all
I can put this into it without it crashing:
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header X-Forwarded-Proto http;
add these
BengalOP
Same result; site works but images don't
what version of next are you using?
BengalOP
14.0.4
I also tried 13
(the latest non-canary 13 release)
can you check the log for nginx on the panel?
BengalOP
This is what you mean right?
yes
what is the url for the image from your cms?
BengalOP
/_next/image?url=https%3A%2F%2Fstrapi.kwekerijvantuyl.nl%2Fuploads%2Ftmp_1e7c6dfaa4.png&w=3840&q=75
Or the direct url:
strapi.kwekerijvantuyl.nl/uploads/tmp_1e7c6dfaa4.png
strapi.kwekerijvantuyl.nl/uploads/tmp_1e7c6dfaa4.png
@Bengal Click to see attachment
the url from log seem wrong
BengalOP
No, the url from the log is the right one
The CMS images work
So they do not throw an error
As you can see here
not all of the image come from cms?
BengalOP
The statically served images from nextjs do not work
ah ok
BengalOP
No, specifically the ones that do not come from the CMS don't work
The CMS images do work
can you show the
next.config.js
BengalOP
> The weird part is that images which are loaded externally are actually loading properly (so any image which is not directly from the Next application itself loads perfectly fine, even if it is under a subdomain on the same server).🙂
try comment out
i18n
BengalOP
Doesn't make a difference
are you importing the image or put them in public and use url string?
BengalOP
I'm importing them
I believe that is the preferred way of NextJS right?
yes
BengalOP
I can try importing them from public using the url string, but I would prefer to do it via "the preferred way" (oh the irony ;p )
I think you could try changing one of them and see if it works
BengalOP
Yes exactly
Lemme check
cp one of them to public folder and change the src path
BengalOP
Yess that works
As I kind of expected ;p
So the problem really lays in importing the image
oh lol
well but it should work with importing
BengalOP
That's correct
try remove those directive in nginx
BengalOP
And I would really like it to work with importing, since (though I'm not 100% sure about this) it helps with image optimization right?
@Ray try remove those directive in nginx
BengalOP
I think it works, but it might be because it cached the image
I put the minimum cache time to 0, but it might still cache it, since it does the same with the banner on my homepage
which image did you change?
BengalOP
The banner image on the top
No, these were cached beforehand, but should be removed already
Those two are the CMS images
They look like this on my end
BengalOP
Yes!
look like if the url start with http and it will work lol
https://kwekerijvantuyl.nl/_next/image?url=https://kwekerijvantuyl.nl/header-news.jpg&w=1080&q=75
BengalOP
That is probably because of my next config
Oops wrong config
that one is local
hmm this should affect that if the images are imported directly
BengalOP
Should I change it to http and try again?
have you try
next@canary
?BengalOP
I'm assuming it won't work, because when images are imported they use localhost
No I haven't, should I?
Are those stable? 🙂
@Bengal Should I change it to http and try again?
no, if local image, the url should be start with _next
@Bengal No I haven't, should I?
try and see if it work first lol
BengalOP
what is the yarn command for that?
yarn add next@14.0.5-canary.31?
yarn add next@canary
BengalOP
Ahh alright
Doesn't make a difference :/
does it work on your pc?
with
next build
&& next start
?BengalOP
Yeah everything works fine locally
Even the images
ah
BengalOP
Shoot I didn't mention that in the issue, only on my stackoverflow post, I'm sorry😅
are you able to try deploying it on vercel?
BengalOP
No, I don't have a vercel account
Nevermind, appaerently I do
well if it work on vercel, then should be something wrong in Plesk
BengalOP
Do you know what could be causing this behavior?
I'm actually almost certain it is a Plesk issue, or some domain resolve issue
how Plesk deploying it? docker?
or just node
BengalOP
Plesk uses Phusion Passenger
BengalOP
Honestly I'm not 100% sure, I think it is some sort of docker variant which also handles http requests, but I'm not 100% sure
Phusion Passenger (informally also known as mod_rails and mod_rack among the Ruby community) is a free web server and application server with support for Ruby, Python and Node.js. It is designed to integrate into the Apache HTTP Server or the nginx web server, but also has a mode for running standalone without an external web server.[3] Phusion Passenger supports Unix-like operating systems, and is available as a gem package, as a tarball, or as native Linux packages.
Wikipedia has spoken
BengalOP
Which link was that? xD
If it is the one from /_next/static then yes, those do work
BengalOP
Doesn't work for me
https://kwekerijvantuyl.nl/_next/image?url=https://kwekerijvantuyl.nl/_next/static/media/side_images-2.b52276a8.jpg&w=640&q=60
this one does
I put your domain in front and it will work
BengalOP
Ahh yes you're right!
if it run fine on vercel, then should be something on Plesk end
BengalOP
What could then be the issue on Plesks end? Something where the localhost resolves to the wrong address?
no idea lol
maybe nginx setting
BengalOP
Hmm could be
https://kwekerijvantuyl.nl/_next/image?url=https://kwekerijvantuyl.nl/_next/static/media/logo-tesco.b00d9e94.png&w=256&q=75
all image work if add your domain in front😆
BengalOP
Interesting.... 😄
https://github.com/vercel/next.js/blob/9986e822637ca70efd4de8e0cb923798b684f4b9/packages/next/src/shared/lib/image-loader.ts#L60
maybe try to find out where is config.path
maybe try to find out where is config.path
BengalOP
config.path isn't the problem right? The problem lies within encodeURIComponent if I'm not mistaking
Since encodeURIComponent returns /_next/static/media/logo-tesco.b00d9e94.png while we want it to return https://kwekerijvantuyl.nl/_next/static/media/logo-tesco.b00d9e94.png
yeah could be not
but I don't have issue with importing image
so still unsure what could be the cause
your have multiple site have this issue on Plesk right?
BengalOP
Agreed, replacing encodeURIComponent to add the URL in front is kind of "avoiding" the issue instead of solving it :/
Yes, correct
All sites that use the app/ directory
The pages/ directory works perfectly fine, also with image imports
maybe check with their github issue?
BengalOP
Plesk isn't very popular to host Next JS applications in, so I couldn't find anything
does they support app router?
BengalOP
They support Node JS applications in general, I don't know about app routers
I suppose I will just wait for their response, I'll update you tomorrow, heading to my bed now. Thanks for all the help today Ray! â¤ï¸
ok np
Southern rough shrimp
hey @Bengal did you ever find out the solution for this problem?
currently facing the same problem and I genuinely dont know what caused it.. I am using next@^13.4.19 with the sharp package ^0.33.1
Using the Image component causes this problem
Using the Image component causes this problem
using a nginx server to host the frontend and backend
https://domain.com/_next/image?url=%2Fimages%2Fheadshot2.png&w=96&q=75
returns:
"url" parameter is valid but upstream response is invalid
accessing the image directly using the /images/headshot2.png is working
on the server I get the error
upstream image response failed for /images/headshot2.png TypeError: fetch failed
spent the last day scowering over forums and things to find a fix but nothing is fixing the issue
Southern rough shrimp
Also, it works in development but does not work in production, so I assume nginx is messing something up
problem started happening out of the blue and I didnt change my nginx config or anything
Southern rough shrimp
solved it.. had to add a piece of code to nginx config
BengalOP
Perfect! For me I had to manually start the application from the server itself instead of via Plesk, no idea why this went wrong
BengalOP
A little update, I actually have not solved the issue yet 😦 . What happened is that the Plesk Support engineer actually started the application on my public IP instead of on the domain name. The issue did now become more clear. The following request from Next.JS in image-optimizer.js:
Goes to (per example): http://localhost:3000/_next/static/media/abs.38cff8d4.jpg
However, this localhost is for some reason not passed to the Phusion Passenger Container, but instead just checks the local address of the server. Now since there is now an application running on this address, it returns a 404 error, as this image is hosted on a different website. However, before it returned a forbidden error, as this port was not alllowed to be accessed. Nevertheless, the issue is that either Next.JS makes a request to the server IP, or Plesk does not forward the request to the corresponding Phusion Passenger container. Does anyone know which config to add such that it is forwarded to the correct location?
const mocked = (0, _mockrequest.createRequestResponseMocks)({
url: href,
method: _req.method || "GET",
headers: _req.headers,
socket: _req.socket
});
Goes to (per example): http://localhost:3000/_next/static/media/abs.38cff8d4.jpg
However, this localhost is for some reason not passed to the Phusion Passenger Container, but instead just checks the local address of the server. Now since there is now an application running on this address, it returns a 404 error, as this image is hosted on a different website. However, before it returned a forbidden error, as this port was not alllowed to be accessed. Nevertheless, the issue is that either Next.JS makes a request to the server IP, or Plesk does not forward the request to the corresponding Phusion Passenger container. Does anyone know which config to add such that it is forwarded to the correct location?
BengalOP
It seems that the method handleRequest is the problem here, as the mocked request is passed to this function, and this function seems to be the one introducing the localhost:3000 parameter. Does anyone know how necessary this is and if I can change some sort of config? Or maybe where I can find more details about this problem, so why this resolves to my actual server instead of the container which is hosting the site?
https://nextjs.org/docs/app/building-your-application/optimizing/open-telemetry#httpmethod-nextroute
https://nextjs.org/docs/app/building-your-application/optimizing/open-telemetry#httpmethod-nextroute
BengalOP
Small update on this issue, it only happens in Next 14. I upgraded one of my other sites to Next 14 (without transferring anything to the app directory), and it showed the same issue. After reverting it back to Next 13 the issue was solved again