Troubleshooting an HTTP 400 Invalid Hostname Error

Troubleshooting an HTTP 400 Invalid Hostname Error

Recently we had a problem connecting a 3rd party to an API that we run in our environment; the emails between the developers kept running for a few days, one party claiming the issue is network related while the other party claiming its the API that has a problem. Our developers sent a request using postman and had a successful response, while the 3rd party sent the same request but receives an HTTP 400 invalid hostname error. Since our team can get a normal response, they thought the other team has a network issue, while the other team can reach the server but get a 400 error using the same exact request URI, so they thought its an API issue.


TLDR;

The client is missing a header in the request, something sysadmins can better troubleshoot than developers. Sysadmins are vital for your infrastructure, and cloud technologies cannot compensate them, neither can developers.


To break down the problem, our sysadmin team was called in to help; this team includes both Network and System administrators. Thankfully the issue was resolved within 15 minutes. One of the quickest troubleshooting methods is elimination by cause to narrow down the problem as much as possible.

The connecting request is getting back an HTTP 400 invalid hostname error. Although for experienced sysadmins this is obviously not a network problem since there was a response, at the same time the code 400 indicates a client side issue (something wrong with the request) but sometimes it can happen due to a server misconfiguration (the site hostname it connects to). The confusing part was that they are both sending the same request URI using the same tool.

To solve the problem, we thought to go down one step at a time.

  1. stop any firewall rules connecting to this server to eliminate the probability of a firewall rule blocking anything. (Firewall eliminated)
  2. run wireshark on the server and capture traffic, while the request is being made, it was clear that there was traffic coming in and out, SYN, SYN-ACK, ACK a full TCP handshake followed by TLS client and server hello, where the response went back with the aforementioned error (HTTP 400 invalid hostname) on the client side. We made sure that the connecting IP address belongs to the 3rd party so this is exactly the one request we are looking for. Server logs indicate the same problem (Network eliminated)
  3. Now we narrowed it down to the server itself, Since this server hosts multiple projects then the only way for the server to distinguish for which site the request is intended for is the site name (This is a common configuration in webservers, let it be Nginx, Apache, IIS...etc.) for example we have

https://www.example1.com and https://www.example2.com

Both sites are hosted on the same server, hence the same IP address and both serving on port 443 HTTPS, so the only way the server can route the request properly is by passing it to the correct site configured with this name. Therefore servers misconfigured with the proper name will show the HTTP 400 invalid hostname error. Now we did review the server and all sites seem to have the correct configuration. Additionally our team can get a proper response, so the server should be fine and we should turn back to our 3rd party request. Still the server is not fully eliminated as a cause. to do so we run the following test

4. A quick test was to put a hello world index.html page on the site and open a bowser from the client side and it opened nicely. Good to go, then the server is fine as well, our developer can reach normally, the hello world page can be accessed normally but the API request from our 3rd party using postman is failing. Now we can see its narrowed down to this request. (Server configuration eliminated)

5. Now we got back to the client request; they are using postman with the correct URI but getting the 400 invalid hostname, Bingo! the request must be missing the hostname header. adding the correct header to the request solved the problem. Here we were asked the following question

"the URL has the correct site https://www.example.com/some/endpoint/"

Well... Yes but the host request header is missing, this is something the browser or the tool usually does for you behind the scenes, when you connect to a website you are running the following command

GET /path HTTP/1.1
host:www.example.com
....
some-other-headers

Without this host request header the server will not know to which site:port it should route the request and would give you back the 400 invalid response, which totally makes sense. The client request has a problem, it is not sending the proper host request header in order for the server to distinguish it! adding the proper header solved it. Now why was the postman request not sending the host request header in the first place, I have no idea, but these things do happen.

Moral of the story

Many developers today are largely dependent on cloud technologies and tools, they are starting to miss some of the details behind the scenes and how the protocols work. Developers are not sysadmins, there is a difference, and the job of the developer is to focus on solving problems using their code; not wasting time on mysterious server behavior. This is the role of the sysadmin, something many companies today think they can skip because the cloud can compensate them. Guess what! they can't and the sysadmin is a vital skill in any tech company whether it uses on premises or cloud infrastructure.



Hi Monis! You wondered why Postman wouldn't automatically send the Host header; I actually think it's good that it didn't. If it did and you verified the API was working with Postman, then went to implement in an application, it might fail since you forgot to add the Host header. You'd then have to perform a packet capture and compare Postman's output with your own. So making the user explicitly declare the headers is a good practice. It should also be noted that the issue would differ depending on if you were using unencrypted HTTP or TLS. When using TLS, the server won't know which certificate to use to decrypt the payload (which contains headers), and trying all the certificates would be inefficient. This is where Server Name Indicator comes in (SNI), which is an extension to the TLS specification. Postman reads this from the Host header, but not all application libraries will. For example, curl does not use Host header for SNI and will use the URL unless you explicitly use the --resolve or --connect-to parameters.

To view or add a comment, sign in

More articles by Monis Monther

  • I Hate Ubuntu Series Episode 1

    Hi everyone, this is actually not a hate article, but rather an attempt to bridge the gap for sysadmins coming from…

    7 Comments

Others also viewed

Explore content categories