I use AWS Elastic Load Balancing and was surprised to see that my server is unhealthy, yet handles requests without a problem. Upon further investigation, I discovered that the reason for that is the absence of the Accept
header. I logged on the machine and:
curl -XGET -I localhost:80/admin
(which has Accept: */*
by default) returns HTTP 200curl -XGET -I localhost:80/admin -H "Accept:"
(Accept
is set to empty) returns HTTP 404This header is lacking in the raw HTTP request that the load balancer sends:
GET /admin HTTP/1.1
Host: 172.31.32.240
Connection: close
User-Agent: ELB-HealthChecker/2.0
Accept-Encoding: gzip, compressed
…which results in a 404 and "Severe" state in Elastic Beanstalk.
Then, I tested locally and found out that this only happens in production mode. In development, it returns status code 200, regardless of Accept
. What appears to be fixing it is the Webpack middleware. If I comment out this line:
Line 30 in a1813ca
…I can get the same behavior in development mode as well.
npm run build
, then npm run serve
to run Payload in production modecurl -i localhost:3000/admin -H "Accept:"
HTTP/1.1 404 Not Found
with the Express error Cannot GET /admin
Note, however, that requesting a file from the build folder like curl -XGET -I localhost:3000/admin/styles.css -H "Accept:"
correctly returns status 200.
Requests to /admin
should always return status code 200.
Payload version: 1.3.0
Hey @hdodov — we just looked into this in-depth and I have some explanations for you as well as a potential solution.
In production, we are simply leveraging express.static
to serve static files. The Accept
header is necessary to be able to consume html
, etc. from a server response, and being that your health check request does not specify it, Express does not return with any results - thus 404.
This is not something that Payload can control, and further, express.static
does not have any options for how to treat the Accept
header.
Instead, what you could do would be to point your health check to a custom route that you've opened, like /health-check
and have your route return a 200.
Either that, or you could figure out if there is a way to modify the health check request that you are sending from Elastic Load Balancing to add a header to that request, which should be possible. Because really what you're telling Elastic to do is to hit a static file, with no Accept header, which will rightly 404, as there is no Accept header allowing html
response types.
Does that make sense?
Yep, adding a /health
route is exactly what I did. I just thought that maybe it's an issue with Payload, rather than Express.
Looking into this one @hdodov. I was able to recreate.
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.