I'm using ESP8266WiFiMulti, ESP8266WebServer and ArduinoOTA to communicate with my device and perform over-the-air-updates. Everything was working perfectly until I moved the ESP8266 further from the WiFi router. The OTA upload slowed down, which caused upload timeouts after 5 seconds. It fails at a different point each time, usually between 30% and 60%.

How do I increase the OTA timeout to 30 seconds?

Here is the setup code, let me know if you need more:

void startWiFi() {
    ESP8266WiFiMulti wifiMulti;
    wifiMulti.addAP(ssid, password);

void startOTA() {

    ArduinoOTA.onStart([]() {
        Serial.println("Start OTA");
    ArduinoOTA.onEnd([]() {
        Serial.println("\nEnd OTA");
    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
    ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
        else if (error == OTA_END_ERROR) Serial.println("End Failed");

The only timeout I can find is in the espota.py script itself. That is riddled with such lines as:


You would need to scour that program and change them all.


ArduinoOTA uses UDP for communication. Because of that it is unreliable (yes, that's a technical term). It doesn't have any form of retransmit / retry, so if a packet is lost it's lost for good. No amount of increasing of timeouts will make that packet reappear.

So increasing your timeouts most likely will just make it wait longer before failing.

You should consider switching to a more reliable update system which uses TCP instead of UDP - such as downloading an update from a website using ESP8266httpUpdate.


ArduinoOTA uses a combination of both UDP (to initialise and authenticate the connection) and TCP (to make a "back channel" connection back to your computer) to download the actual binary.

The same still applies: you will need to alter the espota.py program to change its timeouts (sock2 is the back-channel object), but there is also one line in ArduinoOTA.cpp that will need to be altered to increase timeouts. Line 294:

int waited = 1000;

This is not strictly the number of milliseconds to wait for incoming data, but it's not far off - it's a 1 millisecond delay in a loop while looking for incoming data. Increasing that will allow more time for the ESP8266 to wait for data to arrive.

But of course, with an unstable WiFi connection YMMV...

  • Thanks for the reply! What's the point of using UDP for firmware upgrades, a critical function? I'm using LittleFS file system, so I can also upload the file, then find a library to do the program switch. – DV82XL Feb 7 at 1:19
  • It's fast, easy to implement packets, light weight and reliable enough for most uses. You're a corner case. – Majenko Feb 7 at 1:21
  • I meant why does ArduinoOTA use UDP instead of TCP? That seems like a bad design decision. Firmware updates should be lossless. – DV82XL Feb 7 at 1:25
  • 1
    @Juraj So it does. It initiates the connection with UDP first then the ESP8266 makes a reverse connection to the computer running espota.py to pull down the binary. Serves me right for trying to decipher Python at 2 in the morning. It's bad enough at the best of times when I'm full of coffee... – Majenko Feb 7 at 10:42
  • 1
    @StarCat Back when I was at university it was called Unreliable vs Reliable transmission. Transmission that doesn't retry vs transmission that retries. Maybe it's a regional thing. – Majenko Feb 7 at 10:50

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.