14

I am getting for the first time

Caused by: java.io.IOException: HTTP/1.1 header parser received no bytes

(my app seemed to work up to now...)

HttpClient httpClient = HttpClient.newHttpClient();
            HttpRequest httpRequest = HttpRequest
                    .newBuilder()
                    .GET()
                    .uri(URI.create("..."))
                    .header("Content-Type", "application/json")
                    .build();

            System.out.print(httpRequest.toString()); // dbg - it's ok

            HttpResponse<String> response = null;
            try {
                response = httpClient.send(httpRequest,
                        HttpResponse.BodyHandlers.ofString());
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }

            if (response != null && response.statusCode() == 200) {
                JSONObject jsonObject = new JSONObject(response.body());
                JSONArray jsonArray = jsonObject.getJSONArray("data");
                ObjectMapper objectMapper = ObjectMapperCreator.getNewObjectMapper();
                try {
                    if (jsonArray.length() > 0) {
                        correctlyCaught = true;
                        return objectMapper.readValue(jsonArray.get(0).toString(), GeocodingResponse.class);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

this is the code. Why am I getting this error?

Ob-la-di
  • 143
  • 1
  • 1
  • 5

4 Answers4

13

The HTTP header is the very first thing that the server will respond with.

And that error says that it is empty. In effect then, this error, loosely translated, means: "The server sent absolutely nothing back and hung up".

This also explains why 'it worked before'. It's not you; it's that server. It's broken, offline, or has been updated or replaced so that it can no longer deal with your request.

This + other linked SO answers suggest you force HTTP/1.1 mode - you're just massaging how you send your request in the hope that you can shape it so that the server doesn't choke on it. Most likely the server is just offline and all you have to do is wait a while or get in contact with the administrator. Also try connecting to the URL with e.g. curl or your browser to see what's going on.

Another common reason for this is that they just took their HTTP (as in, the non-HTTPS side) offline or it died and nobody noticed because nobody* connects with HTTP anymore. Then the fix is probably to just.. toss an 's' in that URL. Browsers silently upgrade http:// urls into https:// urls via various mechanisms all the time, but java HTTP libraries don't do that unless you explicitly ask for it (by making that url https based). So, check that URL (it's not in the paste): If it's http://, consider trying again with https:// instead.

Just a sidenote:

} catch (IOException | InterruptedException e) {
               e.printStackTrace();
           }
           if (response != null && response.statusCode() == 200) {

Please, don't do this. What you've written here is: If an error occurs, log it inappropriately (syserr is not an appropriate place to log things) and then silently do nothing. You're setting yourself up for wild goose chases and failure down the road. Do yourself a favour. Go into your IDE, right now, find the place where you configure autocompletion templates. And get rid of that useless, cringe inducing e.printStackTrace() and make that throw new RuntimeException("Uncaught", e);. When things occurs that you did not bother to handle, the last thing you'd want is 'silently do nothing'. You WANT the crash with the appropriate stack trace.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
8

Please try passing HTTP version:

HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.build();
Vasif
  • 668
  • 4
  • 10
  • 1
    This is the correct answer. The server receiving the HTTP request must not support HTTP 2, so we have to explicitly set the version in the request to 1.1. – CompEng88 Aug 18 '21 at 13:26
  • @CompEng88 It's not that easy. For me, it was some kind of firewall on the server. I kept getting responses for a couple of minutes, then nothing. – Lakatos Gyula Sep 12 '21 at 07:27
1

This solution works for me,

HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.build();
Prabhakaran
  • 3,900
  • 15
  • 46
  • 113
0

In my case, it appeared to be the corporate VPN that caused this issue. Are you using a corporate VPN or proxy?

Another user shared a similar experience with this problem here.

Khalil
  • 175
  • 2
  • 8
  • In my case as well the Office VPN / Proxy was the root cause. The Proxy/VPN was meddling with the requests and was causing this exception. Once it was disabled the responses were coming fine – Nandhan Thiravia Jan 06 '23 at 07:14
  • Yup, it can be very pesky. Glad to hear you got it resolved. – Khalil Jan 07 '23 at 08:45