You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
IPv6 address still in duplicate address detection is skipped and never retried #1915
A link-local IPv6 address that is still in duplicate address detection (DAD, "tentative") cannot be bound. new_socket treats EADDRNOTAVAIL as benign, logs a warning and returns None, so the interface gets no responder socket. add_interface then drops the multicast group membership it had just joined for that interface.
Nothing retries the bind. Once DAD finishes (about a second later) the address is usable, but the address set has not changed, so a caller that reconciles on address changes has no reason to call async_update_interfaces again. The instance stays without IPv6 on that interface until some unrelated address change.
WARNING zeroconf: Address not available when binding to ('fe80::943f:67ff:fe01:cbb8', 5353, 0, 11), it is expected to happen on some systems
The instance has an IPv4 sender only. Calling async_update_interfaces() a few seconds later binds the link-local sender.
Seen with 0.151.2 on Linux (arm64, Python 3.13). The same window exists whenever an interface comes up shortly before construction or a reconcile, for example at container or host boot.
Suggested fix
Treat EADDRNOTAVAIL on an IPv6 address as retryable: remember the interfaces skipped for that reason and schedule one short internal retry (a few seconds), for both construction and async_update_interfaces.
Filtering tentative addresses up front is not an option, since ifaddr does not expose IFA_F_TENTATIVE.
Workaround
esphome/device-builder#2864 runs one extra async_update_interfaces ten seconds after startup and after each binding change.
Hi, I’d like to take this one if you’re not already on it.
Plan: when new_socket hits EADDRNOTAVAIL for a link-local IPv6 address that’s still tentative (DAD), schedule a short retry of the bind instead of dropping the interface. I’d also keep the multicast membership until the retry gives up, and add a test for it.
Would you prefer the retry inside the engine, or should the caller be notified so it can call async_update_interfaces again?
Activity
Sharawey74 commentedon Oct 25, 2026
Hi, I’d like to take this one if you’re not already on it.
Plan: when
new_sockethitsEADDRNOTAVAILfor a link-local IPv6 address that’s still tentative (DAD), schedule a short retry of the bind instead of dropping the interface. I’d also keep the multicast membership until the retry gives up, and add a test for it.Would you prefer the retry inside the engine, or should the caller be notified so it can call
async_update_interfacesagain?