Fix IPv6 address handling in bind config and ifaddr parsing (#3111)
authorFirdavs Murodov <firdavs.murodov@gmail.com>
Sun, 8 Feb 2026 18:36:30 +0000 (19:36 +0100)
committerGitHub <noreply@github.com>
Sun, 8 Feb 2026 18:36:30 +0000 (19:36 +0100)
music_assistant/controllers/streams/streams_controller.py
music_assistant/controllers/webserver/controller.py
music_assistant/helpers/util.py
music_assistant/helpers/webserver.py

index 7dcd944774ee0eebcd7c28963bc653ac98ba69ff..87b393a3467edb3a92c04cda195036a39564242b 100644 (file)
@@ -281,10 +281,10 @@ class StreamsController(CoreController):
                 key=CONF_BIND_IP,
                 type=ConfigEntryType.STRING,
                 default_value="0.0.0.0",
-                options=[ConfigValueOption(x, x) for x in {"0.0.0.0", *ip_addresses}],
+                options=[ConfigValueOption(x, x) for x in {"0.0.0.0", "::", *ip_addresses}],
                 label="Bind to IP/interface",
                 description="Start the stream server on this specific interface. \n"
-                "Use 0.0.0.0 to bind to all interfaces, which is the default. \n"
+                "Use 0.0.0.0 or :: to bind to all interfaces, which is the default. \n"
                 "This is an advanced setting that should normally "
                 "not be adjusted in regular setups.",
                 category="generic",
index fac4f762cb6bcbb96e683d83e4b16859d5a8de94..dddbdff3a0c44b28c40b3ec627aee66bf5015c5a 100644 (file)
@@ -226,10 +226,10 @@ class WebserverController(CoreController):
                 key=CONF_BIND_IP,
                 type=ConfigEntryType.STRING,
                 default_value="0.0.0.0",
-                options=[ConfigValueOption(x, x) for x in {"0.0.0.0", *ip_addresses}],
+                options=[ConfigValueOption(x, x) for x in {"0.0.0.0", "::", *ip_addresses}],
                 label="Bind to IP/interface",
                 description="Bind the (web)server to this specific interface. \n"
-                "Use 0.0.0.0 to bind to all interfaces. \n"
+                "Use 0.0.0.0 or :: to bind to all interfaces. \n"
                 "Set this address for example to a docker-internal network, "
                 "when you are running a reverse proxy to enhance security and "
                 "protect outside access to the webinterface and API. \n\n"
index 5d57e0e095584dfc82a7b9d5f01a5385834fe686..834b0cee03a55fdf734e00bf4e298f7746476ca5 100644 (file)
@@ -304,7 +304,8 @@ async def get_ip_addresses(include_ipv6: bool = False) -> tuple[str, ...]:
             for ip in adapter.ips:
                 if ip.is_IPv6 and not include_ipv6:
                     continue
-                ip_str = str(ip.ip)
+                # ifaddr returns IPv6 addresses as (address, flowinfo, scope_id) tuples
+                ip_str = ip.ip[0] if isinstance(ip.ip, tuple) else ip.ip
                 if ip_str.startswith(("127", "169.254")):
                     # filter out IPv4 loopback/APIPA address
                     continue
index 39bf87f52c0d4f8357d35899e6d22ac637a1397f..5097d53e03b67a46788490e8debdca369de04320 100644 (file)
@@ -94,7 +94,7 @@ class Webserver:
             self._webapp.router.add_route("*", "/{tail:.*}", self._handle_catch_all)
         await self._apprunner.setup()
         # set host to None to bind to all addresses on both IPv4 and IPv6
-        host = None if bind_ip == "0.0.0.0" else bind_ip
+        host = None if bind_ip in ("0.0.0.0", "::") else bind_ip
         try:
             self._tcp_site = web.TCPSite(
                 self._apprunner, host=host, port=bind_port, ssl_context=ssl_context