[GH-ISSUE #1266] configportal - softAPdisconnect FAILED and AsyncTCP.cpp:1268] begin(): bind error: -8 #1081

Open
opened 2026-02-28 01:28:26 +03:00 by kerem · 1 comment
Owner

Originally created by @bmoniey on GitHub (Jun 27, 2021).
Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1266

Basic Infos

Hardware

WiFimanager Branch/Release: Master

Esp32:

Hardware: esp32doit-devkit-v1

Core Version: Espressif 32 (3.2.1) > DOIT ESP32 DEVKIT V1

Description

Problem description

I am trying to us wifi manager and ESPAsyncWebServer
I would like to start the AsyncWebServer after exiting from AP portal.

The AsyncWebServer works OK if there are saved credentials which allow a connection without using a portal.

When a portal is needed the WiFi Manager seems to leave its server behind without unbinding from port 80.

When my AsyncWebServer tries to bind to port 80 it fails.

I see that the shutdownConfigPortal() is not succesful.

Settings in IDE

Module: DOIT ESP32 DEVKIT V1

Additional libraries:

using platform io

[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino

lib_deps = https://github.com/tzapu/WiFiManager.git
https://github.com/me-no-dev/ESPAsyncWebServer.git
https://github.com/lorol/LITTLEFS.git
ESPmDNS

extra_scripts = replace_fs.py
upload_port = COM24
monitor_port = COM24
monitor_speed = 115200
debug_tool = esp-prog
debug_init_break = tbreak setup

Sketch

#include <Arduino.h>
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#include <ESPAsyncWebServer.h>
#include <WebServer.h>
#include <LITTLEFS.h>
#include <AsyncTCP.h>
#include <ESPmDNS.h>

AsyncWebServer server(80);

void setup_fs();
void setup_wifi();
void setup_server();

void setup(){
// put your setup code here, to run once:
Serial.begin(115200);
delay(200);
setup_fs();
setup_wifi();
setup_server();
}

void loop() {
// put your main code here, to run repeatedly:

}

void setup_wifi() {
// WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it.
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP

//WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wm;

//reset settings - wipe credentials for testing
wm.resetSettings();

// Automatically connect using saved credentials,
// if connection fails, it starts an access point with the specified name ( "AutoConnectAP"),
// if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect())
// then goes into a blocking loop awaiting configuration and will return success result

bool res;
// res = wm.autoConnect(); // auto generated AP name from chipid
// res = wm.autoConnect("AutoConnectAP"); // anonymous ap
res = wm.autoConnect("AutoConnectAP","password"); // password protected ap

if(!res) {
    Serial.println("Failed to connect");
    // ESP.restart();
} 
else {
    //if you get here you have connected to the WiFi    
    Serial.println("connected...yeey :)");
}

//setup mdns
Serial.println("Starting mDNS");
if(!MDNS.begin("esp32")) {
Serial.println("Error starting mDNS");
}
}

void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}

void setup_server(){
Serial.println("Starting web server...");
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
//readFile(LITTLEFS,"/index.html");
request->send(LITTLEFS, "/index.html", String(), false);
});

server.on("/mango.png", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/mango.png", "image/png");
});
server.on("/apple.png", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/apple.png", "image/png");
});
server.on("/banana.png", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/banana.png", "image/png");
});
server.on("/grape.png", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/grape.png", "image/png");
});
server.on("/strawberry.png", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/strawberry.png", "image/png");
});
server.on("/orange.png", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/orange.png", "image/png");
});

// Route to load style.css file

server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/style.css", "text/css");
});

 // Route to load scripts.js file

server.on("/scripts.js", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LITTLEFS, "/scripts.js", "text/js");
});

server.onNotFound(notFound);
server.begin();
}

void setup_fs(){
Serial.println("Mounting file system\n");
if(!LITTLEFS.begin()){
Serial.println("An Error has occurred while mounting LITTLEFS");
return;
}
}

Debug Messages

Mounting file system

*wm:[1] resetSettings
*wm:[1] SETTINGS ERASED
*wm:[1] AutoConnect
*wm:[1] No Credentials are Saved, skipping connect
*wm:[2] Starting Config Portal
*wm:[2] AccessPoint set password is VALID
*wm:[2] Disabling STA
*wm:[2] Enabling AP
*wm:[1] StartAP with SSID: AutoConnectAP
*wm:[1] AP IP address: 192.168.4.1
*wm:[1] Starting Web Portal
*wm:[2] HTTP server started
*wm:[2] Config Portal Running, blocking, waiting for clients...
*wm:[2] NUM CLIENTS: 1
*wm:[2] <- HTTP Root
*wm:[2] <- HTTP Wifi
*wm:[2] WiFi Scan SYNC started
*wm:[2] WiFi Scan completed in 5320 ms
*wm:[1] 9 networks found
*wm:[2] DUP AP: Eisenmont
*wm:[2] DUP AP: Eisenmont
*wm:[2] DUP AP: Dankushome
*wm:[2] AP: -78 Eisenmont
*wm:[2] AP: -80 SINGLE_SPEED24
*wm:[2] AP: -85 MORAN-Network
*wm:[2] AP: -86 Dankushome
*wm:[2] AP: -88 SETUP-D5A7
*wm:[2] AP: -92 Asher
*wm:[2] <- HTTP Root
*wm:[2] <- Request redirected to captive portal
[E][WebServer.cpp:633] _handleRequest(): request handler not found
*wm:[2] <- Request redirected to captive portal
*wm:[2] <- HTTP Root
*wm:[2] <- HTTP Root
[E][WebServer.cpp:633] _handleRequest(): request handler not found
*wm:[2] <- Request redirected to captive portal
[E][WebServer.cpp:633] _handleRequest(): request handler not found
*wm:[2] <- Request redirected to captive portal
*wm:[2] <- HTTP Root
*wm:[2] <- HTTP Root
*wm:[2] NUM CLIENTS: 1
*wm:[2] <- HTTP Root
*wm:[2] <- Request redirected to captive portal
*wm:[2] <- HTTP Root
[E][WebServer.cpp:633] _handleRequest(): request handler not found
*wm:[2] <- Request redirected to captive portal
*wm:[2] <- HTTP Root
*wm:[2] <- HTTP WiFi save
*wm:[2] processing save
*wm:[2] Connecting as wifi client...
*wm:[2] setSTAConfig static ip not set, skipping
*wm:[1] Connecting to NEW AP: MORAN-Network
*wm:[1] connectTimeout not set, ESP waitForConnectResult...
*wm:[2] Connection result: WL_CONNECTED
*wm:[1] Connect to new AP [SUCCESS]
*wm:[1] Got IP Address:
*wm:[1] 192.168.1.111
*wm:[2] shutdownConfigPortal
*wm:[0] [ERROR] disconnect configportal - softAPdisconnect FAILED
*wm:[2] restoring usermode STA
*wm:[2] wifi status: WL_CONNECTED
*wm:[2] wifi mode: STA
*wm:[2] configportal closed
*wm:[1] config portal exiting
connected...yeey :)
Starting mDNS
Starting web server...
[E][AsyncTCP.cpp:1268] begin(): bind error: -8

Originally created by @bmoniey on GitHub (Jun 27, 2021). Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1266 ### Basic Infos #### Hardware WiFimanager Branch/Release: Master Esp32: Hardware: esp32doit-devkit-v1 Core Version: Espressif 32 (3.2.1) > DOIT ESP32 DEVKIT V1 ### Description Problem description I am trying to us wifi manager and ESPAsyncWebServer I would like to start the AsyncWebServer after exiting from AP portal. The AsyncWebServer works OK if there are saved credentials which allow a connection without using a portal. When a portal is needed the WiFi Manager seems to leave its server behind without unbinding from port 80. When my AsyncWebServer tries to bind to port 80 it fails. I see that the shutdownConfigPortal() is not succesful. ### Settings in IDE Module: DOIT ESP32 DEVKIT V1 Additional libraries: using platform io [env:esp32doit-devkit-v1] platform = espressif32 board = esp32doit-devkit-v1 framework = arduino lib_deps = https://github.com/tzapu/WiFiManager.git https://github.com/me-no-dev/ESPAsyncWebServer.git https://github.com/lorol/LITTLEFS.git ESPmDNS extra_scripts = replace_fs.py upload_port = COM24 monitor_port = COM24 monitor_speed = 115200 debug_tool = esp-prog debug_init_break = tbreak setup ### Sketch #include <Arduino.h> #include <WiFiManager.h> // https://github.com/tzapu/WiFiManager #include <ESPAsyncWebServer.h> #include <WebServer.h> #include <LITTLEFS.h> #include <AsyncTCP.h> #include <ESPmDNS.h> AsyncWebServer server(80); void setup_fs(); void setup_wifi(); void setup_server(); void setup(){ // put your setup code here, to run once: Serial.begin(115200); delay(200); setup_fs(); setup_wifi(); setup_server(); } void loop() { // put your main code here, to run repeatedly: } void setup_wifi() { // WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it. WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around WiFiManager wm; //reset settings - wipe credentials for testing wm.resetSettings(); // Automatically connect using saved credentials, // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"), // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect()) // then goes into a blocking loop awaiting configuration and will return success result bool res; // res = wm.autoConnect(); // auto generated AP name from chipid // res = wm.autoConnect("AutoConnectAP"); // anonymous ap res = wm.autoConnect("AutoConnectAP","password"); // password protected ap if(!res) { Serial.println("Failed to connect"); // ESP.restart(); } else { //if you get here you have connected to the WiFi Serial.println("connected...yeey :)"); } //setup mdns Serial.println("Starting mDNS"); if(!MDNS.begin("esp32")) { Serial.println("Error starting mDNS"); } } void notFound(AsyncWebServerRequest *request) { request->send(404, "text/plain", "Not found"); } void setup_server(){ Serial.println("Starting web server..."); server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //readFile(LITTLEFS,"/index.html"); request->send(LITTLEFS, "/index.html", String(), false); }); server.on("/mango.png", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/mango.png", "image/png"); }); server.on("/apple.png", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/apple.png", "image/png"); }); server.on("/banana.png", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/banana.png", "image/png"); }); server.on("/grape.png", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/grape.png", "image/png"); }); server.on("/strawberry.png", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/strawberry.png", "image/png"); }); server.on("/orange.png", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/orange.png", "image/png"); }); // Route to load style.css file server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/style.css", "text/css"); }); // Route to load scripts.js file server.on("/scripts.js", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/scripts.js", "text/js"); }); server.onNotFound(notFound); server.begin(); } void setup_fs(){ Serial.println("Mounting file system\n"); if(!LITTLEFS.begin()){ Serial.println("An Error has occurred while mounting LITTLEFS"); return; } } ### Debug Messages Mounting file system *wm:[1] resetSettings *wm:[1] SETTINGS ERASED *wm:[1] AutoConnect *wm:[1] No Credentials are Saved, skipping connect *wm:[2] Starting Config Portal *wm:[2] AccessPoint set password is VALID *wm:[2] Disabling STA *wm:[2] Enabling AP *wm:[1] StartAP with SSID: AutoConnectAP *wm:[1] AP IP address: 192.168.4.1 *wm:[1] Starting Web Portal *wm:[2] HTTP server started *wm:[2] Config Portal Running, blocking, waiting for clients... *wm:[2] NUM CLIENTS: 1 *wm:[2] <- HTTP Root *wm:[2] <- HTTP Wifi *wm:[2] WiFi Scan SYNC started *wm:[2] WiFi Scan completed in 5320 ms *wm:[1] 9 networks found *wm:[2] DUP AP: Eisenmont *wm:[2] DUP AP: Eisenmont *wm:[2] DUP AP: Dankushome *wm:[2] AP: -78 Eisenmont *wm:[2] AP: -80 SINGLE_SPEED24 *wm:[2] AP: -85 MORAN-Network *wm:[2] AP: -86 Dankushome *wm:[2] AP: -88 SETUP-D5A7 *wm:[2] AP: -92 Asher *wm:[2] <- HTTP Root *wm:[2] <- Request redirected to captive portal [E][WebServer.cpp:633] _handleRequest(): request handler not found *wm:[2] <- Request redirected to captive portal *wm:[2] <- HTTP Root *wm:[2] <- HTTP Root [E][WebServer.cpp:633] _handleRequest(): request handler not found *wm:[2] <- Request redirected to captive portal [E][WebServer.cpp:633] _handleRequest(): request handler not found *wm:[2] <- Request redirected to captive portal *wm:[2] <- HTTP Root *wm:[2] <- HTTP Root *wm:[2] NUM CLIENTS: 1 *wm:[2] <- HTTP Root *wm:[2] <- Request redirected to captive portal *wm:[2] <- HTTP Root [E][WebServer.cpp:633] _handleRequest(): request handler not found *wm:[2] <- Request redirected to captive portal *wm:[2] <- HTTP Root *wm:[2] <- HTTP WiFi save *wm:[2] processing save *wm:[2] Connecting as wifi client... *wm:[2] setSTAConfig static ip not set, skipping *wm:[1] Connecting to NEW AP: MORAN-Network *wm:[1] connectTimeout not set, ESP waitForConnectResult... *wm:[2] Connection result: WL_CONNECTED *wm:[1] Connect to new AP [SUCCESS] *wm:[1] Got IP Address: *wm:[1] 192.168.1.111 *wm:[2] shutdownConfigPortal *wm:[0] [ERROR] disconnect configportal - softAPdisconnect FAILED *wm:[2] restoring usermode STA *wm:[2] wifi status: WL_CONNECTED *wm:[2] wifi mode: STA *wm:[2] configportal closed *wm:[1] config portal exiting connected...yeey :) Starting mDNS Starting web server... [E][AsyncTCP.cpp:1268] begin(): bind error: -8
Author
Owner

@Zimbu98 commented on GitHub (Sep 19, 2021):

This is the only thing that I could do to solve the problem. (bmoniey helped me but I think we are both not happy with this workaround):

Sketch:

#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager

#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>

//AsyncWebServer server(80);
AsyncWebServer server1(81);

const char* PARAM_MESSAGE = "message";

void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}

void setup() {
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP

// put your setup code here, to run once:
Serial.begin(115200);

// WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it.

//WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wm;

//reset settings - wipe credentials for testing
wm.resetSettings();

wm.setBreakAfterConfig(true);
wm.setCleanConnect(true); // disconnect before connect, clean connect
wm.setCountry("US");

// Automatically connect using saved credentials,
// if connection fails, it starts an access point with the specified name ( "AutoConnectAP"),
// if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect())
// then goes into a blocking loop awaiting configuration and will return success result

bool res;
// res = wm.autoConnect(); // auto generated AP name from chipid
// res = wm.autoConnect("AutoConnectAP"); // anonymous ap
res = wm.autoConnect("AutoConnectAP","password"); // password protected ap

if(!res) {
Serial.println("Failed to connect");
// ESP.restart();
}
else {
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");

}

Serial.print("IP Address: ");
Serial.println(WiFi.localIP());

server1.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Hello, world");
});

// Send a GET request to /get?message=
server1.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String message;
if (request->hasParam(PARAM_MESSAGE)) {
message = request->getParam(PARAM_MESSAGE)->value();
} else {
message = "No message sent";
}
request->send(200, "text/plain", "Hello, GET: " + message);
});

// Send a POST request to /post with a form field message set to
server1.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
String message;
if (request->hasParam(PARAM_MESSAGE, true)) {
message = request->getParam(PARAM_MESSAGE, true)->value();
} else {
message = "No message sent";
}
request->send(200, "text/plain", "Hello, POST: " + message);
});

server1.onNotFound(notFound);

server1.begin();

}

void loop() {
// put your main code here, to run repeatedly:

}

This allows me to access the second webserver at http://192.168.0.30:81 while WifiManager still seems to hold onto port 80. Of course, a restart of the ESP will force WiFiManager to release port 80, but I did not want to require user to do that (because the user will forget this instruction then freak out when webserver doesn't work).

<!-- gh-comment-id:922394824 --> @Zimbu98 commented on GitHub (Sep 19, 2021): This is the only thing that I could do to solve the problem. (bmoniey helped me but I think we are both not happy with this workaround): **Sketch:** #include <WiFiManager.h> // https://github.com/tzapu/WiFiManager #include <Arduino.h> #ifdef ESP32 #include <WiFi.h> #include <AsyncTCP.h> #elif defined(ESP8266) #include <ESP8266WiFi.h> #include <ESPAsyncTCP.h> #endif #include <ESPAsyncWebServer.h> //AsyncWebServer server(80); AsyncWebServer server1(81); const char* PARAM_MESSAGE = "message"; void notFound(AsyncWebServerRequest *request) { request->send(404, "text/plain", "Not found"); } void setup() { WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once: Serial.begin(115200); // WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it. //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around WiFiManager wm; //reset settings - wipe credentials for testing wm.resetSettings(); wm.setBreakAfterConfig(true); wm.setCleanConnect(true); // disconnect before connect, clean connect wm.setCountry("US"); // Automatically connect using saved credentials, // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"), // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect()) // then goes into a blocking loop awaiting configuration and will return success result bool res; // res = wm.autoConnect(); // auto generated AP name from chipid // res = wm.autoConnect("AutoConnectAP"); // anonymous ap res = wm.autoConnect("AutoConnectAP","password"); // password protected ap if(!res) { Serial.println("Failed to connect"); // ESP.restart(); } else { //if you get here you have connected to the WiFi Serial.println("connected...yeey :)"); } Serial.print("IP Address: "); Serial.println(WiFi.localIP()); server1.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/plain", "Hello, world"); }); // Send a GET request to <IP>/get?message=<message> server1.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) { String message; if (request->hasParam(PARAM_MESSAGE)) { message = request->getParam(PARAM_MESSAGE)->value(); } else { message = "No message sent"; } request->send(200, "text/plain", "Hello, GET: " + message); }); // Send a POST request to <IP>/post with a form field message set to <message> server1.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){ String message; if (request->hasParam(PARAM_MESSAGE, true)) { message = request->getParam(PARAM_MESSAGE, true)->value(); } else { message = "No message sent"; } request->send(200, "text/plain", "Hello, POST: " + message); }); server1.onNotFound(notFound); server1.begin(); } void loop() { // put your main code here, to run repeatedly: } This allows me to access the second webserver at http://192.168.0.30:81 while WifiManager still seems to hold onto port 80. Of course, a restart of the ESP will force WiFiManager to release port 80, but I did not want to require user to do that (because the user will forget this instruction then freak out when webserver doesn't work).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/WiFiManager#1081
No description provided.