Intro
Alpine Linux is popular for its simplicity and minimalism, especially in containers and lab environments. Most of the time, this works in your favor, until you run into name resolution issues that seem inconsistent or outright broken. One common example is resolving .local hostnames: DNS appears to work, but tools like ping or curl fail.
This post tries to explain why that happens, why it's expected behavior on Alpine, and how it differs from more full-featured Linux distributions.
Why .local is special, what is mDNS and why it works for you
The .local top-level domain is reserved for Multicast DNS (mDNS) and .local names are meant to be resolved via multicast on the local network, instead of querying a unicast DNS server. This is defined in RFC 6762 and implemented by tools like Avahi and Bonjour.
According to the Alpine documentation, name resolution is handled by musl libc, which only supports classic DNS by default. mDNS isn't integrated into the resolver stack unless additional components are explicitly configured.
As a result, .local hostnames aren't resolved automatically, even though they may work on other distributions where mDNS is integrated transparently.
On glibc-based systems, nss-mdns bridges this gap by wiring mDNS into the system resolver. Alpine doesn't have that option, because musl just doesn't support NSS at all.
Why tools behave differently
Tools like dig or nslookup send DNS queries directly to a DNS server, bypassing most resolver logic. If your DNS server has a .local zone configured, these tools will return valid answers.
Other tools, such as ping or curl, rely on the system resolver, which on Alpine doesn't integrate mDNS into name resolution, so lookups simply fail. The DNS server is never queried, which makes the behavior look confusing.
It's a resolver limitation by design.
Minimal environments make this more obvious
This behavior isn't unique to Alpine and also appears in minimal environments like BusyBox-based or scratch Docker images. As described by Nathan Peck, .local hostnames don't resolve inside such containers unless a full mDNS stack or a DNS forwarding workaround is added. Minimal images simply don't include the pieces needed for multicast name resolution.
Alpine fits into this category - small, efficient, and intentionally minimal. Cute, even, but won't hold your hand.
Key points
.localisn't a regular DNS domain,- Alpine Linux doesn't resolve
.localvia mDNS by default, nslookupworking doesn't mean the system resolver will behave the same,- avoid using
.localfor custom DNS zones if possible; just use something else instead, such as.test,.lab,.internal,.silly,.cuteor whatever you want.
Conclusion
This thing may look like broken DNS, but it's just Alpine's resolver behaving as intended.
Alpine is small and minimal by design, a bit like a fox - quiet, efficient, and not interested in doing more than necessary.
What do you think about it?