My ESP32 HTTPClient GET request always returns 204 or fails

Hey everyone,

I'm working with an ESP32 and running a very simple sketch that sends a GET request using HTTPClient. Everything works, WiFi connects, the countdown displays, and the GET request goes through. Here's my code:

//just note, this is totally custom.
#include "arduino_wifi_secrets.h"

#include <Arduino.h>

#include <WiFi.h>

#include <HTTPClient.h>

void setup() {
  Serial.begin(115200);
  Serial.println("\n\n\n\n");
  WiFi.mode(WIFI_STA);
  WiFi.begin(SECRET_SSID, SECRET_PASS);
  Serial.print("connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("starting in...");
  for (uint8_t i = 10; i > 0; i--) {
    Serial.printf(" %d...", i);
    Serial.flush();
    delay(1000);
  }
  Serial.println();
}

void loop() {
  // wait for WiFi connection
  if (WiFi.status() == WL_CONNECTED) {

    HTTPClient http;

    Serial.println("building GET...");

    http.begin("http://httpbin.org/get");
    http.addHeader("Accept", "*/*");
    http.addHeader("Accept-Language", "en-US,en;q=0.9");
    http.addHeader("Host", "httpbin.org");
    http.addHeader("User-Agent", "ESP32");

    Serial.println("sending GET...");
    // start connection and send HTTP header
    int httpCode = http.GET();

    // httpCode will be negative on internet error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("http stat code: %d\n", httpCode);

      // file found at server
      if (httpCode == 200 || httpCode == 203 || httpCode == 206) {
        String payload = http.getString();
        Serial.println(payload);
      }
    } else {
      Serial.printf("failed due to an internet error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();
  }
  Serial.print("retrying in...");
  for (uint8_t i = 10; i > 0; i--) {
    Serial.printf(" %d...", i);
    Serial.flush();
    delay(1000);
  }
  Serial.println();
}

But when I use "http://httpbin.org/get", I always get "204". And when I try "http://3.233.51.125/get", I get a "connection refused" error, even though it worked fine on my browser with no redirects.
The rest of the code works perfectly, WiFi, serial output, countdowns, and retries, all good!

Thanks for your help in advance!

I'll just use the ESP8266 module and see how that goes for now. If that works, maybe I can have the ESP32 communicate with the ESP8266. That would be the most inefficient way to communicate, ever, to an HTTP web server.

I'm just replying as I go, and apparently I got a code of 200 and a successful response on the ESP8266. But that doesn't quite mean the conversation is quite done. I want to see if I could get this to work on the ESP32.

nope, still 204 for the ESP32...

Actually, apparently, I was told that the newer version of the package is unstable. I'll check that.

Running board "esp32 by Espressif Systems" version 3.0.7, and your sketch works fine for me.

Minor notes: you don't need to #include <Arduino.h> in an .ino file; it gets inserted at the top for you.

I have never seen response codes 203 or 206 in the wild.

@kenb4

it's 3.3.0.

Hmm... still 204... well... okay... here's the core. GitHub - espressif/arduino-esp32: Arduino core for the ESP32

I mean... idk why I included that, but it's OK I guess.

nah, this core's OK for the ESP32. mine's the "WROVER" kit. the report: arduino-esp32/runtime-tests-results/RUNTIME_TESTS_REPORT.md at gh-pages · espressif/arduino-esp32 · GitHub
Actually, they may be kind of unstable.

it may not be resolving the IP correctly, even if I give it DNS IPs.

yep, right. it thinks "18.208.113.193" is ANY URL'S IP address... welp...

I just changed up the code a little, and, uh, turned on Verbose, and got this.

retrying in... 10... 9... 8... 7... 6... 5... 4... 3... 2... 1...
building GET...
[ 21763][V][HTTPClient.cpp:252] beginInternal(): url: http://httpbin.org/get
[ 21764][D][HTTPClient.cpp:303] beginInternal(): protocol: http, host: httpbin.org port: 80 url: /get
IP is... 18.208.113.193
sending GET...
[ 21785][D][HTTPClient.cpp:598] sendRequest(): request type: 'GET' redirCount: 0

[ 21847][D][HTTPClient.cpp:1170] connect():  connected to httpbin.org:80
[ 22669][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'HTTP/1.1 204 No Content'
[ 22669][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'Server: nginx'
[ 22672][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'Date: Thu, 24 Jul 2025 12:00:36 GMT'
[ 22681][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'Connection: keep-alive'
[ 22688][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'Etag: W/"a-bAsFyilMr4Ra1hIU5PyoyFRunpI"'
[ 22698][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'Nel: {"report_to":"heroku-nel","response_headers":["Via"],"max_age":3600,"success_fraction":0.01,"failure_fraction":0.1}'
[ 22714][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'Report-To: {"group":"heroku-nel","endpoints":[{"url":"https://nel.heroku.com/reports?s=FV0D7w5XVIIcfK2o6Gog1HfU5eRjY1gDBlQYI4goyI8%3D\u0026sid=67ff5de4-ad2b-4112-9289-cf96be89efed\u0026ts=1753358436"}],"max_age":3600}'
[ 22738][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'Reporting-Endpoints: heroku-nel="https://nel.heroku.com/reports?s=FV0D7w5XVIIcfK2o6Gog1HfU5eRjY1gDBlQYI4goyI8%3D&sid=67ff5de4-ad2b-4112-9289-cf96be89efed&ts=1753358436"'
[ 22758][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'Via: 1.0 heroku-router'
[ 22766][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: 'X-Powered-By: Express'
[ 22773][V][HTTPClient.cpp:1264] handleHeaderResponse(): RX: ''
[ 22779][D][HTTPClient.cpp:1321] handleHeaderResponse(): code: 204
[ 22784][D][HTTPClient.cpp:642] sendRequest(): sendRequest code=204

http stat code: 204
[ 22801][D][HTTPClient.cpp:393] disconnect(): tcp keep open for reuse

Okay, so I'm just going to use the ESP8266 and connect it to the ESP32 via serial. And the ESP8266 should act as the Wi-Fi module, which should help free up space in the ESP32. And also the ESP8266 I know works for GET requests, and possibly POST requests as well. I don't know why the ESP32 isn't cooperating with me, but it is not. And this is a temporary solution, but not quite the solution. So this topic is still up for discussion. And a big thanks to everyone who participated. (@kenb4)

After connecting to WiFi, can try this resolver loop (should work for both ESP32 and ESP8266)

void loop() {
  Serial.print("Enter host name or dotted-IP-address: ");
  while (Serial.available() <= 0);
  String host = Serial.readStringUntil('\n');
  host.trim();
  Serial.println(host);
  IPAddress srv {};
  if (!WiFi.hostByName(host.c_str(), srv)) {
    Serial.println("Lookup failed");
    return;
  }
  Serial.print("resolved: "); Serial.println(srv);
}

Make sure the Serial Monitor is set to use New Line. Try

  • httpbin.org
  • google.com
  • 1.2.3.4
  • 3.233.51.125
  • just press Enter

@kenb4

Enter host name or dotted-IP-address: www.google.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.google.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.google.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.google.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.google.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.google.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.google.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: 

and

www.yahoo.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.yahoo.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.yahoo.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.yahoo.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.yahoo.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: 

You also said plain IPs in the URL did not work either (different problem: connection refused). The hostByName code hasn't changed recently. Starts with

int NetworkManager::hostByName(const char *aHostname, IPAddress &aResult) {
  static bool hasGlobalV6 = false;
  static bool hasGlobalV4 = false;
  err_t err = ERR_OK;
  const char *servname = "0";
  struct addrinfo *res;

  aResult = static_cast<uint32_t>(0);

  // First check if the host parses as a literal address
  if (aResult.fromString(aHostname)) {
    return 1;
  }

So minor addition to the resolver test

void loop() {
  Serial.print("Enter host name or dotted-IP-address: ");
  while (Serial.available() <= 0);
  String host = Serial.readStringUntil('\n');
  host.trim();
  Serial.println(host);
  IPAddress srv {};
  if (srv.fromString(host)) {
    Serial.print("literal address: "); Serial.println(srv);
  }
  if (!WiFi.hostByName(host.c_str(), srv)) {
    Serial.println("Lookup failed");
    return;
  }
  Serial.print("resolved: "); Serial.println(srv);
}

And as expected

Enter host name or dotted-IP-address: httpbin.org
resolved: 3.229.116.23
Enter host name or dotted-IP-address: 1.2.3.4
literal address: 1.2.3.4
resolved: 1.2.3.4
Enter host name or dotted-IP-address: 3.233.51.125
literal address: 3.233.51.125
resolved: 3.233.51.125

@kenb4
nope, still:

Enter host name or dotted-IP-address: www.google.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: httpbin.org
resolved: 18.208.113.193
Enter host name or dotted-IP-address: www.yahoo.com
resolved: 18.208.113.193
Enter host name or dotted-IP-address: 

The numeric IPs? Trying to see where the problem is.

@kenb4
I believe that the problem is that it can't resolve the IP addresses correctly, and it won't connect to anything when I use direct IPs.