I'm trying to read the actual browser URL server-side (Node.js), but is getting the EC2 instance url.

I have a setup consisting of a Node.js application running on EC2 with a Cloudfront distribution.

My domain, example.com points to the Cloudfront distribution:

Type: CNAME Record
Host: stg (points to a staging server on a subdomain)
Value: xxxxxxxxxxxxxxxx.cloudfront.net

It all works great, just one little snag. My application needs to read the actual url in the browser, but everything in the request object points to the EC2 instance ec2-xx-xx-xxx-xxx.ap-southeast-2.compute.amazonaws.com.

E.g console.log(req.host) // c2-xx-xx-xxx-xxx.ap-southeast-2.compute.amazonaws.com

This is my Nginx setup:

upstream node {
  keepalive 64;

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  server_name example.com *.example.com;

  location / {
    proxy_pass $scheme://node$request_uri;
    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Proto-Version $http2;
    proxy_set_header X-Forwarded-Host $host:$server_port;
    proxy_set_header Host $http_host;
    proxy_set_header domain https://stg.example.com; # Temp fix

I have hardcoded a header in Nginx proxy_set_header domain https://stg.example.com; which I can read on the application level, however it doesn't seem quite right.

Is there a better way?


Add the Host header to the whitelist of headers to forward to the origin server in the CloudFront cache behavior settings.

By default CloudFront rewrites this header.


Behavior If You Don't Configure CloudFront to Cache Based on Header Values... CloudFront sets the value to the domain name of the origin that is associated with the requested object.


Adding Host to the whitelist should remedy your issue.

But it will also create new issues depending on how you have configured your origin and how/whether you are using SSL on the backend. If the origin is accessed over SSL then the dzzzexample.cloudfront.net can't be used to access your distribution from the browser's address bar, unless the back-end certificate matches the configured Origin Domain Name. There is a reason for this behavior change, and it is correct behavior on the part of CloudFront, but possibly beyond the scope of this question. See HTTP 502 Status Code Bad Gateway in the CloudFront Developer Guide for a thorough explanation of this condition.


If you access http://stg.example.com/ or https://stg.example.com/, your browser should display exactly that address. You don't need do do anything for this to happen.

If your browser changes the address to c2-xx-xx-xxx-xxx.ap-southeast-2.compute.amazonaws.com, there is an active redirection that causes that, and you must find where that is configures and cancel it.

  • So the question is not about getting the address in the browser, it's about reading it server-side from the request headers. It's currently pointing to EC2 but I'd like to read the example.com address (which is in the browser's address bar). I have updated the question so it's more clear. – ChrisRich Aug 15 '18 at 9:28
  • If the browser shows the correct name in the address bar, then it will send the same name to the server in the Host request header. If something different arrives at your server, then something on the way must modify it, probably some kind of proxy. – RalfFriedl Aug 15 '18 at 10:10
  • @RalfFriedl that isn't quite correct. By default, CloudFront rewrites the Host header to match the backend. – Michael - sqlbot Aug 15 '18 at 16:31
  • Then you have to stop CloudFront from doing it. After the Host name has been rewritten, you can't restore it, you can just guess. – RalfFriedl Aug 16 '18 at 5:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.