diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp
index bb41dfa18c0..a94b1419414 100644
--- a/libraries/WiFi/src/WiFiGeneric.cpp
+++ b/libraries/WiFi/src/WiFiGeneric.cpp
@@ -963,26 +963,26 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event)
             WiFiSTAClass::_setStatus(WL_DISCONNECTED);
         }
         clearStatusBits(STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT);
-        if(first_connect && ((reason == WIFI_REASON_AUTH_EXPIRE) ||
-        (reason >= WIFI_REASON_BEACON_TIMEOUT)))
-        {
-            log_d("WiFi Reconnect Running");
-            WiFi.disconnect();
-            WiFi.begin();
+
+        bool DoReconnect = false;
+        if(reason == WIFI_REASON_ASSOC_LEAVE) {                                     //Voluntarily disconnected. Don't reconnect!
+        }
+        else if(first_connect) {                                                    //Retry once for all failure reasons
             first_connect = false;
+            DoReconnect = true;
+            log_d("WiFi Reconnect Running");
         }
-        else if(WiFi.getAutoReconnect()){
-            if((reason == WIFI_REASON_AUTH_EXPIRE) ||
-            (reason >= WIFI_REASON_BEACON_TIMEOUT && reason != WIFI_REASON_AUTH_FAIL))
-            {
-                log_d("WiFi AutoReconnect Running");
-                WiFi.disconnect();
-                WiFi.begin();
-            }
+        else if(WiFi.getAutoReconnect() && _isReconnectableReason(reason)) {
+            DoReconnect = true;
+            log_d("WiFi AutoReconnect Running");
         }
-        else if (reason == WIFI_REASON_ASSOC_FAIL){
+        else if(reason == WIFI_REASON_ASSOC_FAIL) {
             WiFiSTAClass::_setStatus(WL_CONNECT_FAILED);
         }
+        if(DoReconnect) {
+            WiFi.disconnect();
+            WiFi.begin();
+        }
     } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
 #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
         uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr);
@@ -1066,6 +1066,36 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event)
     return ESP_OK;
 }
 
+bool WiFiGenericClass::_isReconnectableReason(uint8_t reason) {
+    switch(reason) {
+        //Timeouts (retry)
+        case WIFI_REASON_AUTH_EXPIRE:
+        case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
+        case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT:
+        case WIFI_REASON_802_1X_AUTH_FAILED:
+        case WIFI_REASON_HANDSHAKE_TIMEOUT:
+        //Transient error (reconnect)
+        case WIFI_REASON_AUTH_LEAVE:
+        case WIFI_REASON_ASSOC_EXPIRE:
+        case WIFI_REASON_ASSOC_TOOMANY:
+        case WIFI_REASON_NOT_AUTHED:
+        case WIFI_REASON_NOT_ASSOCED:
+        case WIFI_REASON_ASSOC_NOT_AUTHED:
+        case WIFI_REASON_MIC_FAILURE:
+        case WIFI_REASON_IE_IN_4WAY_DIFFERS:
+        case WIFI_REASON_INVALID_PMKID:
+        case WIFI_REASON_BEACON_TIMEOUT:
+        case WIFI_REASON_NO_AP_FOUND:
+        case WIFI_REASON_ASSOC_FAIL:
+        case WIFI_REASON_CONNECTION_FAIL:
+        case WIFI_REASON_AP_TSF_RESET:
+        case WIFI_REASON_ROAMING:
+            return true;
+        default:
+            return false;
+    }
+}
+
 /**
  * Return the current channel associated with the network
  * @return channel (1-13)
diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h
index 62642b43dc7..2f670a34d05 100644
--- a/libraries/WiFi/src/WiFiGeneric.h
+++ b/libraries/WiFi/src/WiFiGeneric.h
@@ -206,7 +206,10 @@ class WiFiGenericClass
 
     static int setStatusBits(int bits);
     static int clearStatusBits(int bits);
-    
+
+  private:
+    static bool _isReconnectableReason(uint8_t reason);
+
   public:
     static int hostByName(const char *aHostname, IPAddress &aResult);