Esp32 OTA constant reboot wtihout WiFi

I've been successful with OTA programming ESP32s. My problem is that any script that uses the OTA code seems to REQUIRE the WiFi be present to operate. That is, in the absence of WiFi, the unit reboots constantly. I get the same behavior using the Arduino sample BasicOTA script, or any ESP32 specific scrips I've found. The OTA upload and my own scripts work fine, as long as WiFi is present, otherwise, this is repeated forever...

Connection Failed! Rebooting...
ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
mode:DIO, clock div:1
entry 0x400806ac

If I bring the device in range of the wifi while this is occurring, the script starts up & runs fine.

I'd like my scripts to run with or without WiFi present, but have the option to bring it in range of the OTA specified WiFi to upload code.

Thanks for any advice.

@guilfordbob, your topic has been moved to a more suitable location on the forum. Introductory Tutorials is for tutorials that e.g. you write, not for questions. Feel free to write a tutorial about the subject once your problem is solved.

This is because the OTA examples manually trigger a reboot when connection is missing, but you can simply remove those lines of code.

I do still want the ability to do an OTA update if the device later gets within range of the WiFi. Physical access is difficult.
Would a good solution be to just delete the ESP.restart(); statement from the example? I have code elsewhere that looks for WiFi & connects when it finds it.

#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

const char* ssid = "..........";
const char* password = "..........";

void setup() {
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");

  // Port defaults to 3232
  // ArduinoOTA.setPort(3232);

  // Hostname defaults to esp3232-[MAC]
  // ArduinoOTA.setHostname("myesp32");

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    .onEnd([]() {
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    .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");


  Serial.print("IP address: ");

void loop() {

Not only, you have to handle also a timeout otherwise the micro will never go outside from while {} statement.

Serial.println("Trying to connect to WiFi");
unsigned long timeout = millis();
while (WiFi.status()  != WL_CONNECTED) {
    if(millis() - timeout > 5000)  {
      Serial.println("\nNo connection to WiFi network");

Maybe you cuould have to handle also reconnection to WiFi in the main loop(), because automatic reconnect with ESP32 will not work always as expected.

// Try to reconnect once every 5 seconds
static unsigned long reconnectTime;
if(WiFi.status()  != WL_CONNECTED && millis() - reconnectTime > 5000) {
   reconnectTime = millis();

   WiFi.begin(ssid, pass);

That reconnect statement is almost identical to the one I have elsewhere in the code!
I'm all set now. I do have to wait until WiFi is available to initialize the OTA initialize code runs ( without the WiFi connect statements in the sample code). Now my code boots and runs fine regardless of WiFi availability. OTA works whenever WiFi is in range, whether it was there at boot or not.
Thanks for the help.