DEV Community

Cover image for AirPlay to Roku fails silently? Debug it with mDNS
Inna
Inna

Posted on

AirPlay to Roku fails silently? Debug it with mDNS

Your iPhone taps Screen Mirroring, the spinner turns, and the Roku never shows up in the list. Nine times out of ten the TV is fine. What broke is discovery: AirPlay finds receivers over mDNS — multicast traffic on 224.0.0.251:5353 — and something on your network is quietly eating those packets. You can prove that in about five minutes with one command, before you reboot anything.

This is a network debugging problem wearing an "AirPlay" costume. Treat it like one.

First, rule out the two boring causes (30 seconds)

Before you touch a single packet, confirm the receiver is even eligible:

  1. Roku OS version. AirPlay 2 needs Roku OS 9.4 or higher. Roku TVs whose model number starts with 5 or 6 need 10.0. Check under Home → Settings → System → About.
  2. AirPlay is switched on. Go to Home → Settings → Apple AirPlay and HomeKit and make sure AirPlay reads On. It ships enabled, but a factory reset or a firmware bump can flip it.

While you're there, turn on Settings → System → Power → Fast TV start. Without it the Roku drops off the network in standby, so it only answers mDNS for a few seconds after you wake it — which looks exactly like a discovery bug.

Same Wi-Fi matters too, but be precise about it. A 2.4 GHz and a 5 GHz band sharing one SSID are the same network. A separate Guest SSID is not, and guest networks block device-to-device traffic on purpose.

The one command that settles the argument

macOS ships dns-sd, part of mDNSResponder. It speaks the exact protocol your iPhone uses to find AirPlay targets, so if dns-sd can't see the Roku, neither can your phone.

Open Terminal and browse for the AirPlay service type:

dns-sd -B _airplay._tcp
Enter fullscreen mode Exit fullscreen mode

A healthy network answers within 2–3 seconds:

Browsing for _airplay._tcp
Timestamp     A/R  Flags  if Domain  Service Type      Instance Name
10:41:07.512  Add  2      6  local.  _airplay._tcp.    Living Room TV
Enter fullscreen mode Exit fullscreen mode

See your Roku's name? Discovery works. The problem is on the iPhone side — skip to the checklist. See nothing after 10 seconds? mDNS is being dropped somewhere between the TV and your Mac. That's the real bug, and now you can point at it.

Two columns in that output are worth reading. A/R marks whether the service was Added or Removed from the network — a receiver that appears then immediately shows Rmv is flapping, usually a standby or Wi-Fi roaming issue. The if column is the interface index; if your Mac is on both Wi-Fi and Ethernet, a hit on the wrong interface tells you the multicast is arriving on a path your phone will never use.

To confirm the receiver resolves to a real host and the standard AirPlay port 7000, look it up by name:

dns-sd -L "Living Room TV" _airplay._tcp local
Enter fullscreen mode Exit fullscreen mode
Living Room TV._airplay._tcp.local. can be reached at Roku.local.:7000
Enter fullscreen mode Exit fullscreen mode

On Linux the equivalent lives in avahi-utils:

sudo apt install avahi-utils
avahi-browse -rt _airplay._tcp
Enter fullscreen mode Exit fullscreen mode

The -r resolves each hit; -t terminates once the cache is drained instead of running forever.

A portable probe when you have no dns-sd

Debugging from a NAS, a container, or a headless box with neither tool installed? A dozen lines of Node do the same PTR query against 224.0.0.251:5353. Node 18+ and one dependency:

npm install multicast-dns@7.2.5
Enter fullscreen mode Exit fullscreen mode
// airplay-probe.js
const mdns = require('multicast-dns')();
const SERVICE = '_airplay._tcp.local';
const seen = new Set();

mdns.on('response', (res) => {
  for (const a of res.answers) {
    if (a.type === 'PTR' && a.name === SERVICE && !seen.has(a.data)) {
      seen.add(a.data);
      console.log('AirPlay receiver advertised:', a.data);
    }
  }
});

mdns.query({ questions: [{ name: SERVICE, type: 'PTR' }] });
console.log(`Querying ${SERVICE} for 5s...`);

setTimeout(() => {
  if (seen.size === 0) {
    console.log('No responders — mDNS is not reaching this host.');
  }
  mdns.destroy();
}, 5000);
Enter fullscreen mode Exit fullscreen mode

Run it:

node airplay-probe.js
Enter fullscreen mode Exit fullscreen mode

An empty result here, on a wired host that should see the TV, is strong evidence the multicast path is broken rather than the Roku.

Reading the result

Two outcomes, two very different fixes.

The Roku shows up in dns-sd but not on your iPhone. Discovery is fine; the phone is the holdout. Sign the iPhone into the same iCloud account you'd expect, toggle Wi-Fi off and on, and restart it. iOS caches Bonjour results aggressively, and a stale cache survives a lot of poking.

Nothing shows up anywhere. Your access point is dropping multicast. Three usual culprits, in the order worth checking:

  • AP isolation / client isolation. Sometimes labeled Wireless Isolation. On means clients can't see each other, which kills Bonjour silently — no error, no warning. Turn it off for the main network.
  • IGMP snooping set too aggressively. On cheap routers it prunes the multicast group the Roku joined. Flip it and re-test both states; there's no universal right answer.
  • Two subnets pretending to be one. Mesh systems and range extenders sometimes put the TV on a different segment than the phone. mDNS is link-local by design — it never crosses a subnet boundary on its own. Bridging it takes a reflector: avahi-daemon with enable-reflector=yes in /etc/avahi/avahi-daemon.conf, or the equivalent "mDNS repeater" toggle some routers hide under their firewall page. If your phone reads 192.168.1.x and the TV reads 192.168.4.x, this is your answer, not isolation.

Checklist

  • [ ] Roku OS 9.4+ (10.0+ for 5xxxx / 6xxxx models)
  • [ ] Settings → Apple AirPlay and HomeKit → AirPlay = On
  • [ ] Fast TV start enabled
  • [ ] Phone and TV on the same SSID, not the Guest network
  • [ ] dns-sd -B _airplay._tcp returns the TV in under 3 seconds
  • [ ] dns-sd -L resolves it to a host and port 7000
  • [ ] AP/client isolation off on the main network

FAQ

Why does the Roku appear one minute and vanish the next?
Standby. Without Fast TV start the Roku stops answering mDNS when the screen is off, so discovery is a coin flip depending on how recently you woke it.

dns-sd shows the TV, but mirroring still fails after it connects. Now what?
Discovery succeeded, so this is a streaming problem, not a lookup one — codec or bandwidth. A busy 2.4 GHz channel is the common cause; move the TV to 5 GHz and retry.

Does this work for AirPlay to an Apple TV too?
Yes. _airplay._tcp is the same service type for every AirPlay 2 receiver, so the identical browse command diagnoses an Apple TV, a HomePod, or a compatible smart TV.

My router has no "AP isolation" setting anywhere.
Look for Wireless Isolation, Client Isolation, or AP/Station isolation — vendors rename it constantly. On mesh gear it's often buried under advanced or guest settings.

The honest limit of this method

A clean dns-sd hit proves one thing and one thing only: the receiver is reachable and willing to accept a mirror stream. It says nothing about whether that stream will play smoothly, and — this is the part people miss — it gives you zero control over the Roku itself. You can't launch an app, scroll a row, or type into the search box from a Bonjour browse. AirPlay throws your screen at the TV; it is not the TV's remote.

So the free fallback, once discovery works, is still a controller of some kind: the physical remote, or any Roku control app on your phone for navigation and text entry. The probe fixes finding the TV. Driving it is a separate job.

Further reading

Top comments (0)