I am getting an "Invalid Host header" message when connecting to webpack-dev-server remotely

JavascriptWebpackWebpack Dev-Server

Javascript Problem Overview


I am using as an environment, a Cloud9.io ubuntu VM Online IDE and I have reduced by troubleshooting this error to just running the app with Webpack dev server.

I launch it with:

webpack-dev-server -d --watch --history-api-fallback --host $IP --port $PORT

$IP is a variable that has the host address $PORT has the port number.

I am instructed to use these vars when deploying an app in Cloud 9, as they have the default IP and PORT info.

The server boots up and compiles the code, no problem, it is not showing me the index file though. Only a blank screen with "Invalid Host header" as text.

This is the Request:

GET / HTTP/1.1
Host: store-client-nestroia1.c9users.io
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 
(KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Accept: 
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
DNT: 1
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8

This is my package.json:

{
  "name": "workspace",
  "version": "0.0.0",
  "scripts": {
    "dev": "webpack -d --watch",
    "server": "webpack-dev-server -d --watch --history-api-fallback --host $IP --port $PORT",
    "build": "webpack --config webpack.config.js"
  },
  "author": "Artur Vieira",
  "license": "ISC",
  "dependencies": {
    "babel-core": "^6.18.2",
    "babel-loader": "^6.2.8",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "babel-preset-stage-0": "^6.24.1",
    "file-loader": "^0.11.1",
    "node-fetch": "^1.6.3",
    "react": "^15.5.4",
    "react-bootstrap": "^0.30.9",
    "react-dom": "^15.5.4",
    "react-router": "^4.1.1",
    "react-router-dom": "^4.1.1",
    "url-loader": "^0.5.8",
    "webpack": "^2.4.1",
    "webpack-dev-server": "^2.4.4",
    "whatwg-fetch": "^2.0.3"
  }
}

This is the webpack.config.js:

const path = require('path');

module.exports = {

  entry: ['whatwg-fetch', "./app/_app.jsx"], // string | object | array
  // Here the application starts executing
  // and webpack starts bundling
  output: {
    // options related to how webpack emits results

    path: path.resolve(__dirname, "./public"), // string
    // the target directory for all output files
    // must be an absolute path (use the Node.js path module)

    filename: "bundle.js", // string
    // the filename template for entry chunks
    
    publicPath: "/public/", // string
    // the url to the output directory resolved relative to the HTML page
  },

  module: {
    // configuration regarding modules

    rules: [
      // rules for modules (configure loaders, parser options, etc.)
      {
        test: /\.jsx?$/,
        include: [
          path.resolve(__dirname, "./app")
        ],
        exclude: [
          path.resolve(__dirname, "./node_modules")
        ],
        loader: "babel-loader?presets[]=react,presets[]=es2015,presets[]=stage-0",
        // the loader which should be applied, it'll be resolved relative to the context
        // -loader suffix is no longer optional in webpack2 for clarity reasons
        // see webpack 1 upgrade guide
      },
      {
        test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ]
      },
      {
        test: /\.(png|jpg|jpeg|gif|svg|eot|ttf|woff|woff2)$/,
        loader: 'url-loader',
        options: {
          limit: 10000
        }
      }
    ]
  },
  
  devServer: {
    compress: true
  }
}

Webpack dev server is returning this because of my host setup. In webpack-dev-server/lib/Server.js line 60. From https://github.com/webpack/webpack-dev-server

My question is how do I setup to correctly pass this check. Any help would be greatly appreciated.

Javascript Solutions


Solution 1 - Javascript

The problem occurs because webpack-dev-server 2.4.4 adds a host check. You can disable it by adding this to your webpack config:

 devServer: {
    compress: true,
    disableHostCheck: true,   // That solved it

 }      

EDIT: Please note, this fix is insecure.

Please see the following answer for a secure solution: https://stackoverflow.com/a/43621275/5425585

Solution 2 - Javascript

I found out, that I need to set the public property of devServer, to my request's host value. Being that it will be displayed at that external address.

So I needed this in my webpack.config.js

devServer: {
  compress: true,
  public: 'store-client-nestroia1.c9users.io' // That solved it
}

Another solution is using it on the CLI:

webpack-dev-server --public $C9_HOSTNAME   <-- var for Cloud9 external IP

Solution 3 - Javascript

This is what worked for me:

Add allowedHosts under devServer in your webpack.config.js:

devServer: {
  compress: true,
  inline: true,
  port: '8080',
  allowedHosts: [
      '.amazonaws.com'
  ]
},

I did not need to use the --host or --public params.

Solution 4 - Javascript

Add this config to your webpack config file when using webpack-dev-server (you can still specify the host as 0.0.0.0).

devServer: {
    disableHostCheck: true,
    host: '0.0.0.0',
    port: 3000
}

Solution 5 - Javascript

The more secure option would be to add allowedHosts to your Webpack config like this:

module.exports = {
devServer: {
 allowedHosts: [
  'host.com',
  'subdomain.host.com',
  'subdomain2.host.com',
  'host2.com'
   ]
  }
};

The array contains all allowed host, you can also specify subdomians. check out more here

Solution 6 - Javascript

Rather than editing the webpack config file, the easier way to disable the host check is by adding a .env file to your root folder and putting this:

DANGEROUSLY_DISABLE_HOST_CHECK=true

As the variable name implies, disabling it is insecure and is only advisable to use only in dev environment.

Solution 7 - Javascript

If you have not ejected from CRA yet, you can't easily modify your webpack config. The config file is hidden in node_modules/react_scripts/config/webpackDevServer.config.js. You are discouraged to change that config.

Instead, you can just set the environment variable DANGEROUSLY_DISABLE_HOST_CHECK to true to disable the host check:

DANGEROUSLY_DISABLE_HOST_CHECK=true yarn start  
# or the equivalent npm command

Solution 8 - Javascript

If you are running webpack-dev-server in a container and are sending requests to it via its container name, you will get this error. To allow requests from other containers on the same network, simply provide the container name (or whatever name is used to resolve the container) using the --public option. This is better than disabling the security check entirely.

In my case, I was running webpack-dev-server in a container named assets with docker-compose. I changed the start command to this:

webpack-dev-server --mode development --host 0.0.0.0 --public assets

And the other container was now able to make requests via http://assets:5000.

Solution 9 - Javascript

on package.json, on "scripts", add the param --disableHostCheck=true Like:

"scripts": {
        "start": "ng serve --host=0.0.0.0 --configuration=dev --disableHostCheck=true"
}

Solution 10 - Javascript

If you are using create-react-app on C9 just run this command to start

npm run start --public $C9_HOSTNAME

And access the app from whatever your hostname is (eg type $C_HOSTNAME in the terminal to get the hostname)

Solution 11 - Javascript

Hello React Developers,

Instead of doing this disableHostCheck: true, in webpackDevServer.config.js. You can easily solve 'invalid host headers' error by adding a .env file to you project, add the variables HOST=0.0.0.0 and DANGEROUSLY_DISABLE_HOST_CHECK=true in .env file. If you want to make changes in webpackDevServer.config.js, you need to extract the react-scripts by using 'npm run eject' which is not recommended to do it. So the better solution is adding above mentioned variables in .env file of your project.

Happy Coding :)

Solution 12 - Javascript

I just experienced this issue while using the Windows Subsystem for Linux (WSL2), so I will also share this solution.

My objective was to render the output from webpack both at wsl:3000 and localhost:3000, thereby creating an alternate local endpoint.

As you might expect, this initially caused the "Invalid Host header" error to arise. Nothing seemed to help until I added the devServer config option shown below.


module.exports = {
  //...
  devServer: {
    proxy: [
      {
	    context: ['http://wsl:3000'],
	    target: 'http://localhost:3000',
	  },
	],
  },
}

This fixed the "bug" without introducing any security risks.

Reference: webpack DevServer docs

Solution 13 - Javascript

While using the default behavior (no config file) with webpack 5 related to this post: [https://stackoverflow.com/a/65268634/2544762`]

"scripts": {
    "dev": "webpack serve --mode development --env development --hot --port 3000"
    ...
    ...
},
"devDependencies": {
    ...
    "webpack": "^5.10.1",
    "webpack-cli": "^4.2.0"
},

With webpack 5 help webpack serve --help:

Usage: webpack serve|server|s [entries...] [options]

Run the webpack dev server.

Options:
  -c, --config <value...>     Provide path to a webpack configuration file e.g.
                              ./webpack.config.js.
  --config-name <value...>    Name of the configuration to use.
  -m, --merge                 Merge two or more configurations using
                              'webpack-merge'.
  --env <value...>            Environment passed to the configuration when it
                              is a function.
  --node-env <value>          Sets process.env.NODE_ENV to the specified value.
  --progress [value]          Print compilation progress during build.
  -j, --json [value]          Prints result as JSON or store it in a file.
  -d, --devtool <value>       Determine source maps to use.
  --no-devtool                Do not generate source maps.
  --entry <value...>          The entry point(s) of your application e.g.
                              ./src/main.js.
  --mode <value>              Defines the mode to pass to webpack.
  --name <value>              Name of the configuration. Used when loading
                              multiple configurations.
  -o, --output-path <value>   Output location of the file generated by webpack
                              e.g. ./dist/.
  --stats [value]             It instructs webpack on how to treat the stats
                              e.g. verbose.
  --no-stats                  Disable stats output.
  -t, --target <value...>     Sets the build target e.g. node.
  --no-target                 Negative 'target' option.
  --watch-options-stdin       Stop watching when stdin stream has ended.
  --no-watch-options-stdin    Do not stop watching when stdin stream has ended.
  --bonjour                   Broadcasts the server via ZeroConf networking on
                              start
  --lazy                      Lazy
  --liveReload                Enables/Disables live reloading on changing files
  --serveIndex                Enables/Disables serveIndex middleware
  --inline                    Inline mode (set to false to disable including
                              client scripts like livereload)
  --profile                   Print compilation profile data for progress steps
  --progress                  Print compilation progress in percentage
  --hot-only                  Do not refresh page if HMR fails
  --stdin                     close when stdin ends
  --open [value]              Open the default browser, or optionally specify a
                              browser name
  --useLocalIp                Open default browser with local IP
  --open-page <value>         Open default browser with the specified page
  --client-log-level <value>  Log level in the browser (trace, debug, info,
                              warn, error or silent)
  --https                     HTTPS
  --http2                     HTTP/2, must be used with HTTPS
  --key <value>               Path to a SSL key.
  --cert <value>              Path to a SSL certificate.
  --cacert <value>            Path to a SSL CA certificate.
  --pfx <value>               Path to a SSL pfx file.
  --pfx-passphrase <value>    Passphrase for pfx file.
  --content-base <value>      A directory or URL to serve HTML content from.
  --watch-content-base        Enable live-reloading of the content-base.
  --history-api-fallback      Fallback to /index.html for Single Page
                              Applications.
  --compress                  Enable gzip compression
  --port <value>              The port
  --disable-host-check        Will not check the host
  --socket <value>            Socket to listen
  --public <value>            The public hostname/ip address of the server
  --host <value>              The hostname/ip address the server will bind to
  --allowed-hosts <value...>  A list of hosts that are allowed to access the
                              dev server, separated by spaces

Global options:
  --color                     Enable colors on console.
  --no-color                  Disable colors on console.
  -v, --version               Output the version number of 'webpack',
                              'webpack-cli' and 'webpack-dev-server' and
                              commands.
  -h, --help [verbose]        Display help for commands and options.

To see list of all supported commands and options run 'webpack --help=verbose'.

Webpack documentation: https://webpack.js.org/.
CLI documentation: https://webpack.js.org/api/cli/.
Made withby the webpack team.
Done in 0.44s.
Solution

So, just add --disable-host-check with the webpack serve command do the trick.

Solution 14 - Javascript

I am using nginx running inside of a docker container to route traffic based on the url.

Adding the following two lines of code in the nginx config file fixed the error Invalid Host header for me. See below for the config file(default.conf).

proxy_set_header Host            $http_host;
proxy_set_header X-Forwarded-For $remote_addr;

First the following is my simple two liner Dockerfile to create the nginx container and then configure it with routing.

FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf

So when the image is built, the default.conf file is copied to the configuration directory inside of the nginx container.

Next the default.conf file looks as follows.

upstream ui {
    # The ui service below is a ui app running inside of a container. Inside of the container, the ui app is listening on port 3000. 
	server ui:3000;
}

upstream node-app {
    # The node-app service below is a server app running inside of a container. Inside of the container, the server is listening on port 8080. 
	server node-app:8080;
}

server {
	listen 80;

	location / {
		# The root path, with is '/' will routed to ui.
		proxy_pass http://ui;

        ################## HERE IS THE FIX ##################
        # Adding the following two lines of code finally made the error "Invalid Host header" go away.

        # The following two headers will pass the client ip address to the upstream server
        # See upstream ui at the very begining of this file.

		proxy_set_header Host            $http_host;
		proxy_set_header X-Forwarded-For $remote_addr;      
	}


	location /api {
		# Requests that have '/api' in the path are rounted to the express server.
		proxy_pass http://node-app;
	}
}
# 

Finally, if you want to take a look at my docker compose file, which has all the services(including nginx), here it is

version: '3'
services:
  # This is the nginx service. 
  proxy:
	build:
      # The proxy folder will have the Dockerfile and the default.conf file I mentioned above. 
	  context: ./proxy 
	ports:
	  - 7081:80

  redis-server:
	image: 'redis'

  node-app:
	restart: on-failure
	build: 
	  context: ./globoappserver
	ports:
	  - "9080:8080"     
	container_name: api-server

  ui:
	build:
	  context: ./globo-react-app-ui
	environment:
		- CHOKIDAR_USEPOLLING=true      
	ports:
	  - "7000:3000"
	stdin_open: true 
	volumes:
	  - ./globo-react-app-ui:/usr/app

  postgres:
	image: postgres
	volumes:
	  - postgres:/var/lib/postgresql/data
	  - ./init-database.sql:/docker-entrypoint-initdb.d/init-database.sql
	environment:
	  - POSTGRES_USER=postgres
	  - POSTGRES_PASSWORD=password

volumes:
  postgres:

Solution 15 - Javascript

Anyone coming here in 2021 on webpack-dev-server v4+,

allowedHosts and disableHostsCheck were removed in favor of allowedHosts: 'all'

To get rid of the error, change your devServer to this:

devServer: {
  compress: true,
  allowedHosts: 'all'
}

Solution 16 - Javascript

For webpack-dev-server 4.7 you can use --allowed-hosts all

npx webpack serve --open --allowed-hosts all

Solution 17 - Javascript

I solved this problem by adding proxying of the host header in the nginx configuration, like this:

server {
    listen 80;
    server_name     localhost:3000;

    location / {
        proxy_pass http://myservice:8080/;

        proxy_set_header HOST $host;
        proxy_set_header Referer $http_referer;
    }
}

I added that:

proxy_set_header HOST $host;

proxy_set_header Referer $http_referer;

Solution 18 - Javascript

Since webpack-dev-server 4 you need to add this to your config:

devServer: {
  firewall: false,
}

Solution 19 - Javascript

note for vue-cli users:

put a file vue.config.js in the root, with the same lines:

module.exports = {
  configureWebpack: {
    devServer: {
      public: '0.0.0.0:8080',
      host: '0.0.0.0',
      disableHostCheck: true,
    }
  }
};

Solution 20 - Javascript

When an HTTP request is made, by default, browsers/clients include the "Host" (from the URL) as part of the headers of the raw HTTP request. As part of an extra security/sanity check that is now commonplace, that Host header must match what is expected by the HTTP server for the server to send you back what you expect.

By default, the Webpack Dev Server (WDS) only accepts incoming HTTP requests with Host header that matches some common hostnames like localhost. When a request comes in with an unexpected Host header, the server still needs to respond with something. So it does the minimum it can: send a response with a standard HTTP error code and a human readable message in the HTML: "Invalid Host header".

Now, as for how to fix this issue, there are basically two options. Tell WDS to accept more (or all) "Host" headers or fix the Host header that is sent with the HTTP request.

Configure Webpack

Generally, it's easier (and more correct) to tell the WDS configuration to allow more "Host"names to be used. By default, WDS only accepts connections from the local development machine and so, by default, only needs to support the hostname localhost. Most commonly this "Invalid Host header" issue comes up when trying to server to other clients on the network. After adding host: '0.0.0.0' to the devServer configuration, WDS needs to be told which names might be used by clients to talk to it. require('os').hostname() is usually (one of) the hostnames but other names could be just as valid. Because of this, WDS accepts a list of allowed names.

module.exports = {
  //...
  devServer: {
    allowedHosts: [
      require('os').hostname(),
      'host.com',
      'subdomain.host.com',
      'subdomain2.host.com',
      'host2.com'
    ]
  }
};

However, sometimes getting this list correct is more trouble than it's worth and it's good enough to just tell WDS to ignore the Host header check. In Webpack 4, it was the disableHostCheck option. In Webpack 5, the allowedHosts option could be set to the single string 'all' (no array).

Create React App (CRA)

The popular package create-react-app uses Webpack internally. CRA has an extra environment variable just to override this particular setting: DANGEROUSLY_DISABLE_HOST_CHECK=true.

Send different Host header

If changing the configuration of Webpack is not possible, the other way to get around this is to change the configuration of the client.

One trick is to use the hosts file on the client machine such that the hostname needed maps to the server's IP.

More common is when a reverse proxy is in-front of WDS. Different proxies have different defaults for the request that's sent to the backend (WDS). You might need to specifically add the Host header to the requests to the backend as VivekDev's answer suggests.

Solution 21 - Javascript

This may happen under two situations:

  1. When you run your webpack-dev-server in cloud-9 or any other online IDE other than localhost.
  2. When you want to run the dev mode on mobile or quickly share the web app with another person via a public URL for your localhost (e.g. using ngrok). For security purposes, you cannot externally access your webpack-dev-server.

You can achieve this in the following way:

devServer: {
    allowedHosts: 'auto' | 'all' | Array[string]
}
  1. If you have no regard for security, you may set allowedHosts to 'all'. (Not recommended, though)
  2. If you use some-host-url to make public URLs, you can do as follows:
devServer: {
 allowedHosts: [
  'host.com',
  'subdomain.host.com'
   ]
  }

For more info: Official doc

Solution 22 - Javascript

I tried the suggestions above but the following solution didn't work for me:

devServer: {
    allowedHosts: 'auto' | 'all' | Array[string]
}

The following solution works for me:

devServer: {
    disableHostCheck: true
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArtur VieiraView Question on Stackoverflow
Solution 1 - Javascript刘芳友View Answer on Stackoverflow
Solution 2 - JavascriptArtur VieiraView Answer on Stackoverflow
Solution 3 - Javascriptirl_irlView Answer on Stackoverflow
Solution 4 - JavascriptSampathView Answer on Stackoverflow
Solution 5 - JavascriptAV PaulView Answer on Stackoverflow
Solution 6 - JavascriptKyle OrdonaView Answer on Stackoverflow
Solution 7 - JavascriptLukas KalbertodtView Answer on Stackoverflow
Solution 8 - JavascriptParkerDView Answer on Stackoverflow
Solution 9 - JavascriptDEV Tiago FrançaView Answer on Stackoverflow
Solution 10 - JavascriptrexView Answer on Stackoverflow
Solution 11 - JavascriptEswar NandamView Answer on Stackoverflow
Solution 12 - Javascriptkillshot13View Answer on Stackoverflow
Solution 13 - JavascriptAlfred HuangView Answer on Stackoverflow
Solution 14 - JavascriptVivekDevView Answer on Stackoverflow
Solution 15 - JavascriptDevin ClarkView Answer on Stackoverflow
Solution 16 - JavascriptMohammad BabaeiView Answer on Stackoverflow
Solution 17 - JavascriptHydrockView Answer on Stackoverflow
Solution 18 - JavascriptadiusView Answer on Stackoverflow
Solution 19 - JavascriptAstor99View Answer on Stackoverflow
Solution 20 - JavascriptCameron TacklindView Answer on Stackoverflow
Solution 21 - JavascriptAnand RajaView Answer on Stackoverflow
Solution 22 - JavascriptRomeo KienzlerView Answer on Stackoverflow