How to fix ESP32 esptool.py Running stub... StopIteration

Problem:

When flashing an ESP32, especially when flashing remotely, you see the following log message

Serial port rfc2217://10.1.2.3.105:4418
Connecting...
Device PID identification is only supported on COM and /dev/ serial ports.
..
Chip is ESP32-S2
Features: WiFi, No Embedded Flash, No Embedded PSRAM, ADC and temperature sensor calibration in BLK2 of efuse V2
Crystal is 40MHz
MAC: 60:55:f9:f0:3a:16
Uploading stub...
Running stub...
Traceback (most recent call last):
  File "/usr/local/bin/esptool.py", line 34, in <module>
    esptool._main()
  File "/usr/local/lib/python3.8/dist-packages/esptool/__init__.py", line 1004, in _main
    main()
  File "/usr/local/lib/python3.8/dist-packages/esptool/__init__.py", line 684, in main
    esp = esp.run_stub()
  File "/usr/local/lib/python3.8/dist-packages/esptool/loader.py", line 912, in run_stub
    p = self.read()
  File "/usr/local/lib/python3.8/dist-packages/esptool/loader.py", line 307, in read
    return next(self._slip_reader)
StopIteration

Solution

This issue occurs not because of a hardware defect but because the latency of the connection is quite high and therefore the timeout occurs before the communication between the script and the bootloader can happen.

In order to fix it, you need to edit the hard-coded default timeout in the esptool.py installation!

First, you need to identify the location of loader.py in your installation. You can simply do that from the following part of the stack trace:

File "/usr/local/lib/python3.8/dist-packages/esptool/loader.py", line 912, in run_stub p = self.read()

In this case, loader.py is located at

/usr/local/lib/python3.8/dist-packages/esptool/loader.py

You need to edit the following line:

MEM_END_ROM_TIMEOUT = 0.05  # short timeout for ESP_MEM_END, as it may never respond

and increase the timeout - my recommendation is to increase it to 2.5 seconds.

… or you can simply change the timeout using the following command:

sed -i -e 's/MEM_END_ROM_TIMEOUT = 0.05/MEM_END_ROM_TIMEOUT = 2.5/g' /usr/local/lib/python3.8/dist-packages/esptool/loader.py

After that, your upload should work just fine.