Skip to content

DNS Resolution Fails with .cluster.local on macOS Due to Local Network Permission Requirements #22654

@tmoschou

Description

@tmoschou

What Happened?

Summary

On macOS, DNS resolution for services using the default .cluster.local domain is unreliable when accessed from the host, due to:

  • Apple/MacOS reserving .local TLD for Multicast DNS (mDNS) and link-local networking
  • Every application (browser, terminal, IDE, etc.) requiring "Local Network" permission in System Settings

This creates a poor user experience as DNS resolution "sometimes" works depending on which application is making the request and whether it has been granted the necessary permissions.

Using --dns-domain=cluster.internal works reliably as a workaround (.internal is an ICANN-reserved TLD for private use) without going through MacOS's Multicast DNS (mDNS) resolver and without requiring special permissions.

Environment

  • macOS Version: macOS Tahoe 26.2
  • minikube Version: v1.38.0
  • Driver: vfkit
  • Network: vmnet-shared (via homebrew)
  • Device enrolled in MDM (Mobile Device Management)

Steps to Reproduce

  1. Start minikube with default DNS domain:
    minikube start --driver=vfkit --network=vmnet-shared

  2. Create a test service:

kubectl create deployment hello-minikube --image=kicbase/echo-server:1.0
kubectl expose deployment hello-minikube --type=LoadBalancer --port=8080
  1. Start the tunnel: sudo minikube tunnel

  2. Verify DNS resolver is configured:

cat /etc/resolver/cluster.local
# Output:
# nameserver 10.96.0.10
# search_order 1

# Or check via scutil
scutil --dns
  1. Verify IP route is configured:
    netstat -nr | grep '^10.96'

  2. Verify can service by IP address
    open "http://$(kubectl get svc/hello-minikube -o go-template='{{ .spec.clusterIP }}'):8080/"

Request served by hello-minikube-58f7c595dd-zxb7f

HTTP/1.1 GET /

Host: 10.108.100.65:8080
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36
  1. Attempt to access the service by DNS address: open http://hello-minikube.default.svc.cluster.local:8080/

Actual Behavior

Image
  • DNS is unreliable,
  • Success depends on whether each application (Browser/IDE/Terminal/etc.) has been granted "Local Network" permission in:
    • macOS Settings → Privacy & Security → Local Network
  • Applications without this permission cannot resolve .cluster.local domains
  • Users experience intermittent failures with no clear indication of the cause

Expected Behavior

DNS resolution should work reliably for all applications without requiring manual permission grants.

Workaround

Use --dns-domain=cluster.internal to minikube start instead of relying on the kubernetes default .cluster.local

minikube delete
minikube start --driver=vfkit --network=vmnet-shared --dns-domain=cluster.internal

kubectl create deployment hello-minikube --image=kicbase/echo-server:1.0
kubectl expose deployment hello-minikube --type=LoadBalancer --port=8080

sudo minikube tunnel

# This now works reliably without Local Network permission
open http://hello-minikube.default.svc.cluster.internal:8080/
Image

Root Cause

The .local TLD is reserved by the IETF in https://datatracker.ietf.org/doc/html/rfc6762 for Multicast DNS (mDNS) and link-local networking. According to the specification:

  • Any fully qualified name ending in .local is considered link-local only (same network segment)
  • DNS queries for .local domains must be sent to the mDNS IPv4 multicast address (224.0.0.251)
  • The .local domain is intended for zero-configuration networking without traditional DNS infrastructure

Kubernetes' use of .cluster.local conflicts with this specification because:

  1. macOS treats .cluster.local as falling under the .local TLD, expecting it to be resolved via mDNS/Bonjour
  2. minikube's vmnet networking doesn't fit the link-local model - it uses unicast DNS resolution, not mDNS multicast
  3. Apple explicitly warns against using .local in unicast DNS contexts, noting it can prevent proper DNS resolution and cause conflicts (https://support.apple.com/en-us/101903)

The .internal TLD, by contrast, is ICANN-reserved for private use and works reliably with traditional unicast DNS resolution, making it a better fit for Kubernetes internal networking.

Proposed Solution

Rather than changing minikube's default DNS domain (which would break compatibility with many tools and Helm charts that assume cluster.local), I propose simply updating documentation with note that users on MacOS may wish to consider configuring --dns-domain=cluster.internal to minikube start in the following sections

Attach the log file

N/A

Operating System

macOS (Default)

Driver

vfkit

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions