Skip to content

macOS resolver ignores /etc/resolver port when nameserver is 127.0.0.1 (breaks dnsmasq defaults) #256659

@zvibo

Description

@zvibo

brew config AND brew doctor output OR brew gist-logs <formula> link

$ brew config
HOMEBREW_VERSION: 5.0.4
ORIGIN: https://github.com/Homebrew/brew
HEAD: 138341781728c93d3886a9d680445d7996682e2a
Last commit: 16 hours ago
Branch: stable
Core tap JSON: 02 Dec 00:26 UTC
Core cask tap JSON: 02 Dec 00:26 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_DISPLAY: /private/tmp/com.apple.launchd.iNBdPjbALM/org.xquartz:0
HOMEBREW_DOWNLOAD_CONCURRENCY: 20
HOMEBREW_EDITOR: emacs
HOMEBREW_FORBID_PACKAGES_FROM_PATHS: set
HOMEBREW_MAKE_JOBS: 10
Homebrew Ruby: 3.4.7 => /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.4.7/bin/ruby
CPU: deca-core 64-bit arm_firestorm_icestorm
Clang: 17.0.0 build 1700
Git: 2.52.0 => /opt/homebrew/bin/git
Curl: 8.7.1 => /usr/bin/curl
macOS: 15.6.1-arm64
CLT: 16.4.0.0.1.1747106510
Xcode: N/A
Rosetta 2: false

$ brew doctor
Your system is ready to brew.

Verification

  • My brew doctor output says Your system is ready to brew. and am still able to reproduce my issue.
  • I ran brew update and am still able to reproduce my issue.
  • I have resolved all warnings from brew doctor and that did not fix my problem.
  • I searched for recent similar issues at https://github.com/Homebrew/homebrew-core/issues?q=is%3Aissue and found no duplicates.
  • My issue is not about a failure to build a formula from source.

What were you trying to do (and why)?

disclaimer: chatgpt helped write this, i only got my setup working this way, not reproduced in a clean environment. if steps to reproduce do not work, please disregard and accept my apologies.


Title: macOS resolver ignores /etc/resolver port when nameserver is 127.0.0.1 (breaks dnsmasq defaults)

Formula: dnsmasq

macOS versions affected: Ventura / Sonoma / Sequoia (all recent releases)


Summary

macOS no longer honors the port field in /etc/resolver/<domain> when the nameserver is 127.0.0.1.
As a result, the standard dnsmasq setup that Homebrew ships
(listen-address=127.0.0.1 + port=5353)
cannot be used with scoped resolver zones.

The resolver override appears to load correctly via scutil --dns, but macOS still sends the DNS request to 127.0.0.1:53, not the specified port (e.g., 5353). dnsmasq is not listening on that port, so lookups time out and macOS falls back to the primary system resolver (usually the router), producing NXDOMAIN.

This makes /etc/resolver/<domain>nameserver 127.0.0.1 unusable with the default Homebrew dnsmasq config.


Reproduction

Expected behavior:
macOS sends traffic to 127.0.0.1:5353.

Actual behavior:
macOS sends to 127.0.0.1:53.
Lookup times out and falls back to router DNS → NXDOMAIN.

scutil --dns misleadingly shows:

resolver {
  domain: dev
  nameserver[0]: 127.0.0.1
  port: 5353
}

…but the actual resolver path never uses that port.


Root cause

Recent macOS versions treat localhost DNS as system-controlled:

  • mDNSResponder + dns_proxy intercept 127.0.0.1:53
  • resolver overrides pointing to 127.0.0.1 are subject to special handling
  • the port directive in /etc/resolver is ignored for localhost addresses

This is macOS behavior, not a dnsmasq bug.


Workaround that actually works

Bind dnsmasq to any non-localhost IP on port 53.
For local-only use, a loopback alias is ideal:

sudo ifconfig lo0 alias 10.0.0.1/24 up

Then in dnsmasq.conf:

listen-address=10.0.0.1
bind-interfaces
port=53

And /etc/resolver/dev:

nameserver 10.0.0.1

This works because macOS only applies the “ignore custom port” behavior to 127.0.0.1.


Suggested action for Homebrew

Not asking for configuration changes or loopback alias management by Homebrew.

Request:
Please add a comment to dnsmasq caveats or default config noting:

On current macOS releases, /etc/resolver/<domain> resolver overrides do not work if the nameserver is 127.0.0.1 and dnsmasq is running on a non-53 port.
To use scoped resolver zones reliably, bind dnsmasq to a non-localhost IP (e.g., a loopback alias like 10.0.0.1) on port 53.

This avoids hours of debugging for users who attempt the traditional /etc/resolver setup.


Additional notes

  • dnsmasq works fine; this is macOS resolver behavior.
  • The workaround does not require PF or system modifications.
  • Binding to a non-localhost IP is stable and survives reboot with a launchd snippet or lo0 alias script.
  • This avoids Apple’s DNS interception without hacking system services.

What happened (include all command output)?

the resolvers stopped working as of the latest update sequoia "15.6.1 (24G90)" update.

adding loopback finally solved the issue after trying everything else.

sudo ifconfig lo0 alias 10.0.0.1/24 up

and bind dnsmasq to 10.0.0.1.

What did you expect to happen?

see above.

Step-by-step reproduction instructions (by running brew commands)

1. Install dnsmasq via Homebrew.
2. Use the shipped defaults:


listen-address=127.0.0.1
port=5353


3. Add a resolver override:


/etc/resolver/dev:
nameserver 127.0.0.1
port 5353


4. Run:


dig dev.test

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions