Skip to content

WLED-AP still active when connected over ethernet - expected to deactivate Wifi completely #5762

Description

@chrisp1001

What happened?

I am using a WLED controller with ethernet port. Therefore I would like to deactivate the WLED AP completely as soon as the controller is running over LAN.
I tried this approach however the Wifi AP is still active: https://www.reddit.com/r/WLED/comments/vmxchv/comment/ie3qxg3/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button

To Reproduce Bug

Not setting a network name and setting AP opens to "Never" in Wifi settings

Expected Behavior

Wifi AP switched off permanently

Install Method

Binary from WLED.me

What version of WLED?

16.0

Which microcontroller/board are you seeing the problem on?

ESP32 with ethernet

Relevant log/trace output

Anything else?

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Activity

  1. changed the title [-]Deactivate Wifi completely[/-] [+]Wled-ap still active when connected over ethernet - expected to deactivate Wifi completely[/+] on Aug 2, 2026
  2. changed the title [-]Wled-ap still active when connected over ethernet - expected to deactivate Wifi completely[/-] [+]WLED-AP still active when connected over ethernet - expected to deactivate Wifi completely[/+] on Aug 2, 2026
  3. softhack007 commented on Aug 2, 2026

    @softhack007
    Member

    similar to

    however PR 5394 intended to save flash by excluding all WiFi functionality. PR 5394 was considered too dangerous for normal use, because it will render esp-now remotes unusable, plus it makes Ethernet config impossible, because AP mode is removed completely.

  4. netmindz commented on Aug 2, 2026

    @netmindz
    Member

    You can also disable the AP mode in the config

  5. chrisp1001 commented on Aug 2, 2026

    @chrisp1001
    Author

    You can also disable the AP mode in the config

    I couldn't make it work as described above. Let me know if you have a different solution.

  6. chrisp1001 commented on Aug 2, 2026

    @chrisp1001
    Author

    Btw, this issue has been addresses here in past: tartinesKiller@47943c4

  7. netmindz commented on Aug 2, 2026

    @netmindz
    Member

    @chrisp1001 - no just use

    Image
  8. chrisp1001 commented on Aug 2, 2026

    @chrisp1001
    Author

    @chrisp1001 - no just use

    It doesn't work like this unfortunately. You may have read this in the link I mentioned in my inital post.

  9. softhack007 commented on Aug 2, 2026

    @softhack007
    Member

    @coderabbitai please analyse the source code in our 16_x branch. What happens if WLED is connected via ethernet, and apMode is set to 'Never'? Is the behaviour different from previous releases like v0.14.4 (tag)?

  10. coderabbitai commented on Aug 2, 2026

    @coderabbitai
    Contributor
    🧩 Analysis chain

    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    printf '%s\n' '== Relevant refs =='
    git branch -a --no-color | grep -E '16_x|v0\.14\.4' || true
    git tag -l 'v0.14.4' || true
    
    printf '%s\n' '== Locate configuration and network symbols =='
    rg -n -i -C 3 '\bapMode\b|AP\s*mode|WIFI_AP|ETH\.|Ethernet|ETHERNET' \
      -g '*.{cpp,h,ino,json}' . | head -n 500
    
    printf '%s\n' '== Candidate source files =='
    fd -t f -e cpp -e h -e ino . | grep -Ei '(wifi|network|ethernet|wled)' | head -n 200

    Length of output: 34057


    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    repo='wled/WLED'
    refs=('16_x' 'v0.14.4')
    files=(
      'wled00/wled.cpp'
      'wled00/network.cpp'
      'wled00/cfg.cpp'
      'wled00/const.h'
      'wled00/wled.h'
      'wled00/src/dependencies/network/Network.cpp'
      'wled00/src/dependencies/network/Network.h'
    )
    
    tmp=$(mktemp -d)
    trap 'rm -rf "$tmp"' EXIT
    
    for ref in "${refs[@]}"; do
      safe_ref=${ref//[^A-Za-z0-9]/_}
      mkdir -p "$tmp/$safe_ref"
      printf '\n== Resolve %s ==\n' "$ref"
      gh api "repos/$repo/commits/$ref" --jq '.sha'
      for file in "${files[@]}"; do
        out="$tmp/$safe_ref/${file//\//__}"
        if gh api -H 'Accept: application/vnd.github.raw+json' \
          "repos/$repo/contents/$file?ref=$ref" >"$out" 2>/dev/null; then
          printf 'Fetched %s\n' "$file"
        else
          printf 'Not present at %s: %s\n' "$ref" "$file"
        fi
      done
    done
    
    printf '\n== Definitions and decision paths: 16_x ==\n'
    rg -n -i -C 8 'AP_BEHAVIOR|apBehavior|initAP\s*\(|initInterfaces\s*\(|findWiFi\s*\(|isConnected\s*\(|isEthernet\s*\(|ETH_GOT_IP|ETH_DISCONNECTED' "$tmp/16_x" || true
    
    printf '\n== Definitions and decision paths: v0.14.4 ==\n'
    rg -n -i -C 8 'AP_BEHAVIOR|apBehavior|initAP\s*\(|initInterfaces\s*\(|findWiFi\s*\(|isConnected\s*\(|isEthernet\s*\(|ETH_GOT_IP|ETH_DISCONNECTED' "$tmp/v0_14_4" || true
    
    printf '\n== Focused source diff ==\n'
    diff -u \
      "$tmp/v0_14_4/wled00__wled.cpp" \
      "$tmp/16_x/wled00__wled.cpp" \
      | grep -E -C 12 'AP_BEHAVIOR|apBehavior|initAP|findWiFi|Ethernet|ETH|^[+-]{1}[^+-]' \
      | head -n 800 || true
    
    diff -u \
      "$tmp/v0_14_4/wled00__network.cpp" \
      "$tmp/16_x/wled00__network.cpp" \
      | grep -E -C 12 'AP_BEHAVIOR|apBehavior|initAP|findWiFi|Ethernet|ETH|^[+-]{1}[^+-]' \
      | head -n 800 || true

    Length of output: 116250


    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    repo='wled/WLED'
    refs=('16_x' 'v0.14.4')
    files=(
      'wled00/data/settings_wifi.htm'
      'wled00/data/settings_wifi.js'
      'wled00/data/settings_wifi.htm.gz'
      'wled00/wled.cpp'
      'wled00/network.cpp'
      'wled00/cfg.cpp'
      'wled00/src/dependencies/network/Network.cpp'
    )
    
    tmp=$(mktemp -d)
    trap 'rm -rf "$tmp"' EXIT
    
    for ref in "${refs[@]}"; do
      d="$tmp/${ref//[^A-Za-z0-9]/_}"
      mkdir -p "$d"
      for file in "${files[@]}"; do
        gh api -H 'Accept: application/vnd.github.raw+json' \
          "repos/$repo/contents/$file?ref=$ref" >"$d/${file//\//__}" 2>/dev/null || true
      done
    
      printf '\n== %s: UI mapping and AP options ==\n' "$ref"
      rg -n -i -C 4 'Never|button.only|AP_BEHAVIOR|behav|access point|AP mode' "$d" || true
    
      printf '\n== %s: initAP/initConnection/setup sequence ==\n' "$ref"
      awk '
        /void WLED::initAP\(/,/^}/ ||
        /void WLED::initConnection\(/,/^}/ ||
        /void WLED::setup\(/,/^void WLED::beginStrip\(/
      ' "$d/wled00__wled.cpp" | sed -n '1,520p'
    
      printf '\n== %s: Ethernet events and connection predicate ==\n' "$ref"
      awk '
        /void WiFiEvent\(/,/^}/
      ' "$d/wled00__network.cpp" | sed -n '1,260p'
      sed -n '70,95p' "$d/wled00__src__dependencies__network__Network.cpp"
    done

    Length of output: 14458


    @softhack007, I compared 16_x (7230b2c) with v0.14.4 (2f6f0d2).

    “Never” maps to apBehavior == 3, which is AP_BEHAVIOR_BUTTON_ONLY.

    When Ethernet has link and an IP address

    In both versions:

    • WLED treats Ethernet as a network connection.
    • The disconnected path does not run.
    • The AP does not start.
    • If code calls initAP() for the normal startup or reconnect flow, initAP() returns immediately for AP_BEHAVIOR_BUTTON_ONLY.
    • The Ethernet-connected event calls WiFi.disconnect(true) when the AP is not active.

    Therefore, with AP opens: Never and a working Ethernet connection, WLED operates through Ethernet and disables the Wi-Fi radio. ESP-NOW needs the Wi-Fi radio. Thus, ESP-NOW remotes are not usable in this intended Ethernet-connected state.

    This behavior is not new in 16_x. v0.14.4 has the same AP guard and the same WiFi.disconnect(true) call in the Ethernet-connected event.

    Difference from v0.14.4

    The relevant difference is Ethernet link-loss detection:

    • 16_x reports Ethernet connected only if ETH.localIP() is non-zero and ETH.linkUp() is true.
    • v0.14.4 reports Ethernet connected when ETH.localIP() is non-zero. It does not check ETH.linkUp().

    As a result, after an Ethernet cable disconnects, 16_x can enter the disconnected/reconnect path as soon as the link is down. v0.14.4 can still consider Ethernet connected while the interface retains its old IP address.

    With AP opens: Never, this difference still does not enable the AP. The initAP() guard prevents it. It can affect Wi-Fi reconnection and the general disconnected state after Ethernet link loss.

    Relevant 16_x locations:

    You are interacting with an AI system.

  11. softhack007 commented on Aug 2, 2026

    @softhack007
    Member

    @coderabbitai please compare the WiFi and ETH implementations between arduino-esp32 v1.0.6 (old release) and arduino-esp32 v2.0.17 (release 16.0). Could it be that differences in the framework's ETH or Network implementation can lead to "Never" not working as expected when ethernet is connected? Please look into static and dynamic(DHCP) IP adress assignments.

  12. coderabbitai commented on Aug 2, 2026

    @coderabbitai
    Contributor
    🧩 Analysis chain

    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    framework_repo='espressif/arduino-esp32'
    wled_repo='wled/WLED'
    framework_refs=('1.0.6' '2.0.17')
    framework_files=(
      'libraries/WiFi/src/WiFiSTA.cpp'
      'libraries/WiFi/src/WiFiGeneric.cpp'
      'libraries/WiFi/src/WiFiSTA.h'
      'libraries/ETH/src/ETH.cpp'
      'libraries/ETH/src/ETH.h'
    )
    wled_files=(
      'wled00/network.cpp'
      'wled00/wled.cpp'
      'wled00/cfg.cpp'
      'wled00/wled.h'
      'wled00/src/dependencies/network/Network.cpp'
      'wled00/src/dependencies/network/Network.h'
    )
    
    tmp="$(mktemp -d)"
    trap 'rm -rf "$tmp"' EXIT
    
    fetch_raw() {
      local repo="$1" ref="$2" file="$3" out="$4"
      gh api -H 'Accept: application/vnd.github.raw+json' \
        "repos/${repo}/contents/${file}?ref=${ref}" >"$out" 2>/dev/null
    }
    
    printf '%s\n' '== Framework tag SHAs =='
    for ref in "${framework_refs[@]}"; do
      printf '%s: ' "$ref"
      gh api "repos/${framework_repo}/commits/${ref}" --jq '.sha'
    done
    
    for ref in "${framework_refs[@]}"; do
      dir="$tmp/framework-$ref"
      mkdir -p "$dir"
      for file in "${framework_files[@]}"; do
        out="$dir/${file//\//__}"
        if fetch_raw "$framework_repo" "$ref" "$file" "$out"; then
          printf 'Fetched %s @ %s\n' "$file" "$ref"
        else
          printf 'Missing %s @ %s\n' "$file" "$ref"
        fi
      done
    done
    
    dir="$tmp/wled-16_x"
    mkdir -p "$dir"
    for file in "${wled_files[@]}"; do
      out="$dir/${file//\//__}"
      fetch_raw "$wled_repo" '16_x' "$file" "$out" || true
    done
    
    printf '%s\n' $'\n== WLED 16_x: configuration and state call sites =='
    rg -n -C 8 \
      '\b(ETH\.config|WiFi\.config|WiFi\.disconnect|ETH\.localIP|ETH\.linkUp|ETH_CONNECTED|ARDUINO_EVENT_ETH|SYSTEM_EVENT_ETH|apBehavior|AP_BEHAVIOR_BUTTON_ONLY)\b' \
      "$dir" || true
    
    for ref in "${framework_refs[@]}"; do
      dir="$tmp/framework-$ref"
      printf '%s\n' $"\n== arduino-esp32 $ref: public APIs and implementations =="
      rg -n -C 10 \
        '\b(config|disconnect|begin|localIP|linkUp|setHostname)\s*\(|(ETH_CONNECTED|ETH_GOT_IP|ETH_DISCONNECTED|ARDUINO_EVENT_ETH|SYSTEM_EVENT_ETH)|tcpip_adapter|esp_netif' \
        "$dir" || true
    done
    
    printf '%s\n' $'\n== Focused framework diffs =='
    for stem in 'libraries__WiFi__src__WiFiSTA.cpp' 'libraries__WiFi__src__WiFiGeneric.cpp' 'libraries__ETH__src__ETH.cpp'; do
      old="$tmp/framework-1.0.6/$stem"
      new="$tmp/framework-2.0.17/$stem"
      if [[ -f "$old" && -f "$new" ]]; then
        printf '\n-- %s --\n' "$stem"
        diff -u "$old" "$new" | \
          grep -E -C 12 '^[+-].*(config|disconnect|tcpip_adapter|esp_netif|ETH|WiFi)|^@@' | \
          head -n 1200 || true
      fi
    done

    Length of output: 143914


    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    framework_repo='espressif/arduino-esp32'
    tmp="$(mktemp -d)"
    trap 'rm -rf "$tmp"' EXIT
    
    fetch() {
      local ref="$1" path="$2"
      gh api -H 'Accept: application/vnd.github.raw+json' \
        "repos/${framework_repo}/contents/${path}?ref=${ref}" >"$tmp/${ref//./_}-$(basename "$path")" 2>/dev/null
    }
    
    printf '%s\n' '== Locate Ethernet source paths in each framework tag =='
    for ref in 1.0.6 2.0.17; do
      printf '\n-- %s --\n' "$ref"
      gh api "repos/${framework_repo}/git/trees/${ref}?recursive=1" --paginate --jq \
        '.tree[].path | select(test("(^|/)(ETH|Network)\\.(cpp|h)$|libraries/(ETH|Network)/"))' \
        | head -n 100
    done
    
    for ref in 1.0.6 2.0.17; do
      for path in \
        'libraries/ETH/src/ETH.cpp' \
        'libraries/ETH/src/ETH.h' \
        'libraries/Network/src/NetworkInterface.cpp' \
        'libraries/Network/src/NetworkInterface.h'; do
        fetch "$ref" "$path" || true
      done
    done
    
    printf '%s\n' $'\n== Framework: Ethernet method implementations =='
    rg -n -C 14 \
      '\b(ETHClass::(begin|config|localIP|linkUp|end)|NetworkInterface::(config|localIP|linkUp)|set_esp_interface_ip|esp_netif_dhcpc_|tcpip_adapter_dhcpc_|tcpip_adapter_set_ip_info)\b' \
      "$tmp" || true
    
    printf '%s\n' $'\n== WLED 16_x: actual Ethernet configuration and event handling =='
    rg -n -C 16 \
      '\b(ETH\.begin|ETH\.config|ETH\.localIP|ETH\.linkUp|WiFi\.disconnect|ETH_GOT_IP|ETH_CONNECTED|ETH_DISCONNECTED|ARDUINO_EVENT_ETH|SYSTEM_EVENT_ETH|apBehavior|AP_BEHAVIOR_BUTTON_ONLY)\b' \
      wled00 platformio.ini 2>/dev/null || true
    
    printf '%s\n' $'\n== WLED 16_x: PlatformIO framework pins =='
    rg -n -C 3 \
      '(platform_packages|framework-arduinoespressif32|arduino-esp32|espressif32)' \
      platformio.ini platforms.ini 2>/dev/null || true

    Length of output: 56856


    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    repo='espressif/arduino-esp32'
    tmp="$(mktemp -d)"
    trap 'rm -rf "$tmp"' EXIT
    
    declare -A paths=(
      ['1.0.6']='libraries/WiFi/src/ETH.cpp libraries/WiFi/src/ETH.h libraries/WiFi/src/WiFiGeneric.cpp'
      ['2.0.17']='libraries/Ethernet/src/ETH.cpp libraries/Ethernet/src/ETH.h libraries/WiFi/src/WiFiGeneric.cpp'
    )
    
    for ref in 1.0.6 2.0.17; do
      mkdir -p "$tmp/$ref"
      for path in ${paths[$ref]}; do
        outfile="$tmp/$ref/${path//\//__}"
        gh api -H 'Accept: application/vnd.github.raw+json' \
          "repos/$repo/contents/$path?ref=$ref" >"$outfile"
      done
    done
    
    printf '%s\n' '== Public Ethernet API signatures =='
    for ref in 1.0.6 2.0.17; do
      printf '\n-- %s --\n' "$ref"
      rg -n -C 4 '\b(bool|IPAddress|uint8_t)\s+(begin|config|linkUp|localIP|setHostname)\s*\(' \
        "$tmp/$ref"/*ETH.h
    done
    
    printf '%s\n' $'\n== Ethernet implementation: begin, config, link, and address access =='
    for ref in 1.0.6 2.0.17; do
      printf '\n-- %s --\n' "$ref"
      rg -n -C 18 \
        '\bETHClass::(begin|config|linkUp|localIP|setHostname|end)\s*\(|\b(tcpip_adapter|esp_netif|esp_eth|SYSTEM_EVENT_ETH|ARDUINO_EVENT_ETH|IP_EVENT_ETH_GOT_IP)\b' \
        "$tmp/$ref"/*ETH.cpp
    done
    
    printf '%s\n' $'\n== Framework Ethernet event translation and dispatch ordering =='
    for ref in 1.0.6 2.0.17; do
      printf '\n-- %s --\n' "$ref"
      rg -n -C 12 \
        '(SYSTEM_EVENT_ETH_CONNECTED|SYSTEM_EVENT_ETH_GOT_IP|ETHERNET_EVENT_CONNECTED|IP_EVENT_ETH_GOT_IP|ARDUINO_EVENT_ETH_CONNECTED|ARDUINO_EVENT_ETH_GOT_IP)' \
        "$tmp/$ref"/*WiFiGeneric.cpp
    done

    Length of output: 24309


    @softhack007, yes. There is a concrete DHCP compatibility problem between these framework versions.

    Main result

    WLED 16_x selects Ethernet DHCP with:

    ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);

    This works in Arduino-ESP32 v1.0.6.

    It does not select DHCP in Arduino-ESP32 v2.0.17.

    INADDR_NONE is 255.255.255.255. In v2.0.17, ETHClass::config() tests only whether local_ip is non-zero. It therefore treats INADDR_NONE as a static address.

    Framework ETH.config(INADDR_NONE, ...) result
    Arduino-ESP32 v1.0.6 DHCP. The code recognizes INADDR_NONE as the non-static case and starts the DHCP client.
    Arduino-ESP32 v2.0.17 Static IPv4 configuration with address 255.255.255.255. The code does not restart the DHCP client.

    This difference can break Ethernet DHCP in the v2.0.17 build.

    Effect on “Never”

    This does not change the AP_BEHAVIOR_BUTTON_ONLY guard. “Never” still prevents normal AP startup.

    However, WLED disables Wi-Fi at Ethernet link-up, not when Ethernet obtains a valid IPv4 address:

    case ARDUINO_EVENT_ETH_CONNECTED:
      if (!apActive) {
        WiFi.disconnect(true);
      }

    The framework emits ETH_CONNECTED before ETH_GOT_IP in both versions.

    Therefore, this sequence is possible with DHCP on v2.0.17:

    1. Ethernet link becomes active.
    2. WLED receives ARDUINO_EVENT_ETH_CONNECTED.
    3. WLED calls WiFi.disconnect(true).
    4. The Wi-Fi radio turns off.
    5. The WLED DHCP call has configured 255.255.255.255 instead of enabling DHCP.
    6. Ethernet does not receive a valid DHCP lease.
    7. No Wi-Fi AP becomes available because “Never” suppresses it.

    There is also an incorrect connection-state risk. WLEDNetwork::isEthernet() checks:

    return (ETH.localIP()[0] != 0) && ETH.linkUp();

    255.255.255.255 is non-zero. If the Ethernet link stays up, WLED can treat this invalid address as an Ethernet connection. This can suppress normal disconnected/reconnect handling.

    Static IPv4 configuration

    Static Ethernet configuration does not have this INADDR_NONE problem.

    WLED uses static Ethernet only when both multiWiFi[0].staticIP and multiWiFi[0].staticGW are non-zero:

    ETH.config(
      multiWiFi[0].staticIP,
      multiWiFi[0].staticGW,
      multiWiFi[0].staticSN,
      dnsAddress
    );

    Both framework versions stop DHCP and install the specified IPv4 configuration for this case. The framework migration from tcpip_adapter to esp_netif does not materially change this WLED static-IP path.

    Framework changes

    Arduino-ESP32 v2.0.17 adds an esp_netif Ethernet interface during ETH.begin(). It still implements the examined ETH.config() path through tcpip_adapter compatibility APIs.

    The important behavior change is the DHCP sentinel check:

    • v1.0.6: local_ip != 0 && local_ip != INADDR_NONE
    • v2.0.17: local_ip != 0

    Thus, the problem is not general Ethernet event handling. It is the meaning of WLED’s DHCP configuration call in v2.0.17.

    Recommended correction

    For Arduino-ESP32 v2.0.17, WLED should request DHCP with zero addresses:

    ETH.config(IPAddress((uint32_t)0), IPAddress((uint32_t)0), IPAddress((uint32_t)0));

    This matches WLED’s Wi-Fi DHCP path and makes v2.0.17 restart the Ethernet DHCP client.

    A second hardening change would validate that ETH.localIP() is a usable unicast address before WLEDNetwork::isEthernet() reports connected. This would prevent 255.255.255.255 from being accepted as a valid Ethernet connection.

    Relevant sources:

    You are interacting with an AI system.

  13. coderabbitai commented on Aug 2, 2026

    @coderabbitai
  14. softhack007 commented on Aug 2, 2026

    @softhack007
    Member

    For Arduino-ESP32 v2.0.17, WLED should request DHCP with zero addresses: ETH.config(IPAddress((uint32_t)0), IPAddress((uint32_t)0), IPAddress((uint32_t)0));

    @coderabbitai please review the arduino-esp32 migration guides for version 2.0.x. is the DHCP suspicion supported by espressif documentation?

  15. coderabbitai commented on Aug 2, 2026

    @coderabbitai
    Contributor
    🧩 Analysis chain

    🤖 web_search executed:

    Search Espressif Arduino-ESP32 official documentation and GitHub repository documentation for Arduino-ESP32 2.0 migration guides. Determine whether the guides mention Ethernet ETH.config(), DHCP configuration, IPAddress(0U), INADDR_NONE, or a behavior change from Arduino-ESP32 1.0.x. Also find the official API documentation or examples for ETH.config() in Arduino-ESP32 2.0.x.

    Length of output: 16994


    🤖 web_search executed:

    `site:docs.espressif.com/projects/arduino-esp32/en/2.0.17 "Migration from 1.x to 2.0" OR "Migration from 1.x to 2.x" Arduino ESP32

    site:docs.espressif.com/projects/arduino-esp32/en/2.0.17 ETH.config DHCP INADDR_NONE IPAddress

    site:github.com/espressif/arduino-esp32 2.0.17 "INADDR_NONE" "ETHClass::config"

    site:github.com/espressif/arduino-esp32 2.0.17 "Migration" "DHCP" Ethernet`

    Length of output: 17639


    @softhack007, no. The Arduino-ESP32 2.0 migration documentation does not explicitly document this DHCP behavior change.

    I did not find a 1.x-to-2.0 migration-guide statement that says any of the following:

    • ETH.config(INADDR_NONE, ...) is unsupported.
    • INADDR_NONE changed meaning in ETH.config().
    • IPAddress(0U) is the required DHCP request value.
    • Ethernet DHCP configuration changed between Arduino-ESP32 1.x and 2.0.x.

    The official Ethernet guide does support one related point. It treats link-up and IP acquisition as separate states:

    • ARDUINO_EVENT_ETH_CONNECTED means the Ethernet link is active.
    • ARDUINO_EVENT_ETH_GOT_IP means Ethernet has an IP address.

    The guide also states that the hostname must be set after Ethernet starts and before DHCP. This supports the conclusion that a link-up event does not prove a usable DHCP address.

    The strongest support for the INADDR_NONE concern is source history, not the migration guide. Espressif previously fixed the exact defect in an older ETHClass::config() implementation:

    “Fix ETH not enabling DHCP when configured with INADDR_NONE”

    That fix added an explicit local_ip != INADDR_NONE test before selecting static configuration. The associated Espressif issue describes the failure mode as static configuration with 255.255.255.255 and DHCP disabled.

    Therefore, I should qualify the earlier conclusion:

    • The claim is not supported by a documented 2.0 migration requirement.
    • The claim is supported by the 1.0.6 and 2.0.17 implementation comparison.
    • The old Espressif fix proves that INADDR_NONE handling in ETH.config() has been a known compatibility-sensitive behavior.
    • ETH.config(IPAddress(0U), ...) is a source-compatible mitigation for the examined 2.0.17 implementation. Espressif migration documentation does not prescribe it.

    A hardware test is still necessary. Test DHCP on the exact release framework package, with both INADDR_NONE and zero-address calls. Log ARDUINO_EVENT_ETH_GOT_IP, ETH.localIP(), gateway, subnet, and DNS values.

    You are interacting with an AI system.

  16. softhack007 commented on Aug 2, 2026

    @softhack007
    Member

    Btw, this issue has been addresses here in past: tartinesKiller@47943c4

    @coderabbitai please analyse the commit referenced by the OP. Can this change solve the DHCP connection state problem? If not, what does it achieve?

  17. coderabbitai commented on Aug 2, 2026

    @coderabbitai
    Contributor
    🧩 Analysis chain

    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    repo='tartinesKiller/WLED'
    sha='47943c4107b09ad566f2f71166c17bed890c0fd6'
    tmp="$(mktemp -d)"
    trap 'rm -rf "$tmp"' EXIT
    
    echo '== Commit metadata and changed files =='
    gh api "repos/$repo/commits/$sha" \
      --jq '{sha, parents: [.parents[].sha], message: .commit.message, files: [.files[] | {filename, status, additions, deletions, patch}]}' \
      >"$tmp/commit.json"
    jq '{sha, parents, message, files: [.files[] | del(.patch)]}' "$tmp/commit.json"
    jq -r '.files[] | "\n== \(.filename) ==\n\(.patch // "(No inline patch returned)")"' "$tmp/commit.json"
    
    parent="$(jq -r '.parents[0]' "$tmp/commit.json")"
    echo
    echo "== Parent: $parent =="
    
    echo '== Relevant source before and after =='
    jq -r '.files[].filename' "$tmp/commit.json" | while IFS= read -r path; do
      echo
      echo "--- $path @ parent ---"
      gh api -H 'Accept: application/vnd.github.raw+json' \
        "repos/$repo/contents/$path?ref=$parent" 2>/dev/null | \
        rg -n -C 20 'ETH\.config|WiFi\.config|INADDR_NONE|staticIP|staticGW|ETH_GOT_IP|ETH_CONNECTED|WiFi\.disconnect|localIP|linkUp' || true
      echo "--- $path @ commit ---"
      gh api -H 'Accept: application/vnd.github.raw+json' \
        "repos/$repo/contents/$path?ref=$sha" 2>/dev/null | \
        rg -n -C 20 'ETH\.config|WiFi\.config|INADDR_NONE|staticIP|staticGW|ETH_GOT_IP|ETH_CONNECTED|WiFi\.disconnect|localIP|linkUp' || true
    done
    
    echo
    echo '== Corresponding paths in WLED 16_x =='
    for path in wled00/network.cpp wled00/src/dependencies/network/Network.cpp wled00/wled.cpp; do
      echo "--- $path ---"
      gh api -H 'Accept: application/vnd.github.raw+json' \
        "repos/wled/WLED/contents/$path?ref=16_x" 2>/dev/null | \
        rg -n -C 20 'ETH\.config|WiFi\.config|INADDR_NONE|staticIP|staticGW|ETH_GOT_IP|ETH_CONNECTED|WiFi\.disconnect|localIP|linkUp' || true
    done

    Length of output: 36995


    @softhack007, no. The referenced commit cannot solve the Ethernet DHCP connection-state problem.

    The commit changes only wled00/wled.cpp. It does not change:

    • ETH.config()
    • INADDR_NONE
    • Ethernet DHCP startup
    • ETH.localIP()
    • ETH.linkUp()
    • NetworkClass::isEthernet()
    • Ethernet events such as ARDUINO_EVENT_ETH_CONNECTED or ARDUINO_EVENT_ETH_GOT_IP

    Therefore, it cannot correct either of these DHCP-related failures:

    1. ETH.config(INADDR_NONE, ...) configures 255.255.255.255 instead of enabling DHCP in a framework that does not recognize INADDR_NONE as the DHCP sentinel.
    2. NetworkClass::isEthernet() accepts a nonzero but invalid Ethernet address while the Ethernet link remains up.

    What the commit achieves

    The commit changes the Wi-Fi fallback policy.

    1. It turns Wi-Fi off when no client SSID exists

    In initConnection(), if WLED_WIFI_CONFIGURED is false and clientSSID is empty, it now runs:

    WiFi.mode(WIFI_OFF);
    return;

    Before this change, WLED started the AP immediately:

    if (!apActive) initAP();
    return;

    This prevents WLED from automatically entering AP mode when the configuration has no Wi-Fi client SSID.

    2. It stops repeated Wi-Fi reconnect attempts when no SSID exists

    The commit adds this condition:

    && *clientSSID != '\0'

    WLED then does not call initConnection() every reconnect interval when it has no SSID to connect to.

    3. It prevents the 12-second fallback from starting an AP in button-only mode

    The commit adds:

    apBehavior != AP_BEHAVIOR_BUTTON_ONLY

    The disconnected-state fallback no longer calls initAP() after 12 seconds when AP mode is button-only.

    This is the part that addresses the historical “AP opens: Never” behavior. In that version, AP_BEHAVIOR_BUTTON_ONLY could still reach the periodic fallback path and start an AP.

    Effect when Ethernet DHCP fails

    If Ethernet link is up but DHCP does not obtain a usable address:

    • The commit does not start Ethernet DHCP.
    • The commit does not validate the Ethernet address.
    • The commit does not change Network.isConnected().
    • The commit can prevent Wi-Fi and AP fallback.

    Thus, the commit can make the device remain unreachable after an Ethernet DHCP failure. It enforces “do not use Wi-Fi/AP” behavior. It does not repair Ethernet connectivity.

    For 16_x, the DHCP investigation must remain focused on wled00/network.cpp and wled00/src/dependencies/network/Network.cpp. The referenced commit is relevant to AP fallback behavior, but not to the Ethernet DHCP configuration or Ethernet connection-state defect.

    You are interacting with an AI system.

  18. softhack007 commented on Aug 2, 2026

    @softhack007
    Member

    the commit can make the device remain unreachable after an Ethernet DHCP failure. It enforces “do not use Wi-Fi/AP” behavior.

    Sounds dangerous 🤔 it basically makes the board unreachable if ethernet startup failed.

  19. chrisp1001 commented on Aug 2, 2026

    @chrisp1001
    Author

    the commit can make the device remain unreachable after an Ethernet DHCP failure. It enforces “do not use Wi-Fi/AP” behavior.

    Sounds dangerous 🤔 it basically makes the board unreachable if ethernet startup failed.

    Well, if there is a DHCP failure there must be an error with the DHCP server or any other network issue. This can be easily fixed by plugging it to any other network with working DHCP. So if a user chooses the option AP opens: 'Never' I think this is an expected behaviour.

  20. added this to the 16.1 milestone on Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions