hardware/mac-studio/remote-access.md

Mac Studio — Chrome Remote Desktop (remote access)

Symptom (2026-10-15)

On https://remotedesktop.google.com/access → Set up remote access on this device, entering the PIN and the Google password returned you to a page stuck on "Setting up…", forever. No error, no installer prompt. Nothing appeared to install.

Root cause

The host was fully installed but its LaunchAgent was explicitly disabled in Dom's login (GUI) domain, so the host service never started and the web setup flow had nothing to hand off to. It just polls forever.

Evidence:

# Service does not exist in the GUI domain at all
launchctl print gui/501/org.chromium.chromoting
#   -> Could not find service "org.chromium.chromoting" in domain for user gui: 501

# ...because it is disabled there
launchctl print-disabled gui/501 | grep chromoting
#   -> "org.chromium.chromoting" => disabled

# Yet everything else is present and healthy
pkgutil --pkgs | grep -i ChromeRemoteDesktop
#   -> com.google.pkg.ChromeRemoteDesktopHost
#      com.google.pkg.ChromeRemoteDesktopHostService
#      com.google.pkg.ChromeRemoteDesktopHostUninstaller
plutil -lint /Library/LaunchAgents/org.chromium.chromoting.plist   # OK
ls /Library/PrivilegedHelperTools/ChromeRemoteDesktopHost.app/Contents/MacOS/
#   -> remoting_me2me_host_service, remoting_me2me_host, libremoting_core.dylib, ...

Timeline detail that confirms the diagnosis: during the failed attempt the setup flow did write its config, so the host binary was reachable and working:

  • /Library/PrivilegedHelperTools/org.chromium.chromoting.json (root-owned 600, the host credentials/config) written at the time of the attempt
  • /Library/PrivilegedHelperTools/org.chromium.chromoting.me2me_enabled marker created at the same minute

The plist itself was fine:

<key>Label</key><string>org.chromium.chromoting</string>
<key>ProgramArguments</key>
<array>
  <string>/Library/PrivilegedHelperTools/ChromeRemoteDesktopHost.app/Contents/MacOS/remoting_me2me_host_service</string>
  <string>--run-from-launchd</string>
</array>
<key>RunAtLoad</key><true/>
<key>LimitLoadToSessionType</key><array><string>Aqua</string><string>LoginWindow</string></array>

Fix

Re-enable the label, then bootstrap it (enable alone does not start a not-yet-loaded agent):

launchctl enable gui/$(id -u)/org.chromium.chromoting
launchctl bootstrap gui/$(id -u) /Library/LaunchAgents/org.chromium.chromoting.plist

No sudo needed for either; both are user-domain operations.

Verify:

launchctl print gui/$(id -u)/org.chromium.chromoting | grep -E 'state|pid|runs'
#   -> state = running, runs = 1, pid = <n>
ps aux | grep remoting_me2me_host_service | grep -v grep

Then refresh the remotedesktop.google.com/access page and redo (or finish) the setup. Because RunAtLoad is true and the label is now enabled, it also survives reboots.

Gotchas

  • Grep for the wrong name and you will think it is dead. The launchd label is org.chromium.chromoting but the process is remoting_me2me_host_service (no "ch" prefix, no "chromoting" in the process name). ps aux | grep -i chromoting returns nothing even when the host is running.
  • The host service opens no TCP listener. It talks to Chrome over its native-messaging path, so lsof -iTCP | grep remoting proving nothing is not evidence of failure.
  • launchctl print-disabled gui/<uid> is the fastest single check for "installed but the page hangs" on any LaunchAgent-hosted service.
  • Screen Recording permission is a separate, still-unverified gate. The CRD host needs Screen Recording (and, for input, Accessibility) in System Settings → Privacy & Security. The user TCC db cannot be read for this (authorization denied), so it has to be checked in the UI if a connection later fails to show the screen. Not yet exercised.

Second failure: the broker daemon (same session)

With the LaunchAgent running, the device appeared on remotedesktop.google.com/access but showed offline, and connecting from another machine failed with "Chrome Remote Desktop failed to start on the remote computer. If this problem persists, please set it up again." "Last online" showed the current time, so it registered and then died.

The real error is in the unified log (the host retries, then gives up):

remoting_me2me_host WARNING remoting/host/mac/agent_process_broker_client.cc:41
  Cannot connect to IPC through server name chromoting.agent_process_broker_mojo_ipc. Endpoint is invalid.
remoting_me2me_host ERROR remoting/host/remoting_me2me_host.cc:1483
  Failed to connect to agent process broker.
launchd[1] [gui/501] failed lookup: name = chromoting.agent_process_broker_mojo_ipc,
  requestor = remoting_me2me_[17828], error = 3: No such process
remoting_me2me_host_service WARNING remoting/host/mac/host_service_main.cc:170
  Host failure count 4/10

Cause: the system-domain broker daemon is not loaded. The plist is present and valid and the label is not in the disabled database, it simply was never bootstrapped:

ls /Library/LaunchDaemons/org.chromium.chromoting.broker.plist   # exists, Disabled=false
plutil -lint /Library/LaunchDaemons/org.chromium.chromoting.broker.plist   # OK
launchctl print system/org.chromium.chromoting.broker
#   -> Could not find service "org.chromium.chromoting.broker" in domain for system
launchctl print-disabled system | grep chromoting
#   -> "org.chromium.chromoting.broker" => enabled   (not disabled, just not loaded)

That daemon is what publishes the Mach service chromoting.agent_process_broker_mojo_ipc:

<key>Label</key><string>org.chromium.chromoting.broker</string>
<key>ProgramArguments</key>
<array><string>/Library/PrivilegedHelperTools/ChromeRemoteDesktopHost.app/Contents/MacOS/remoting_agent_process_broker</string></array>
<key>MachServices</key>
<dict><key>chromoting.agent_process_broker_mojo_ipc</key><true/></dict>

So the host starts, cannot reach the broker, and exits. No crash report is produced, which makes it look like a silent failure.

Fix (needs root)

sudo launchctl bootstrap system /Library/LaunchDaemons/org.chromium.chromoting.broker.plist

exec on this Gateway is not permitted to elevate (elevated is not available right now (runtime=direct)), and sudo -n fails, so this one needs an admin prompt or a Terminal window. A GUI prompt can be raised without a terminal:

osascript -e 'do shell script "/bin/launchctl bootstrap system /Library/LaunchDaemons/org.chromium.chromoting.broker.plist" with administrator privileges'

Confirm the dialog is really on screen before waiting on it: when it is up, SecurityAgent appears as a child process right after the osascript (pgrep -fl SecurityAgent), and osascript sits idle with no output until it is answered or cancelled.

Verified fixed (19:41)

Dom approved the admin prompt. After the bootstrap:

system/org.chromium.chromoting.broker   state = running, runs = 1
  -> 0 .../remoting_agent_process_broker            (root, pid 19250)
501 .../remoting_me2me_host_service --run-from-launchd   (pid 15830)
501 .../remoting_me2me_host --host-config=/Library/PrivilegedHelperTools/org.chromium.chromoting.json
        --ssh-auth-sockname=/tmp/chromoting.dominick.ssh_auth_sock

No further Failed to connect to agent process broker errors and no Host failure count increments after the fix; the last two were at 19:39:11 and 19:40:11, i.e. the failed retries. The host process then stayed up. So the full fix for this machine is both bootstraps, user and system:

launchctl enable gui/$(id -u)/org.chromium.chromoting
launchctl bootstrap gui/$(id -u) /Library/LaunchAgents/org.chromium.chromoting.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/org.chromium.chromoting.broker.plist

Both have RunAtLoad/Disabled=false, so they come back on reboot. If CRD ever goes "offline" again after a macOS update, check the two labels first.

Open items

  • Reading /Library/PrivilegedHelperTools/org.chromium.chromoting.json (host id / config) needs sudo; not read during this diagnosis.
  • Why the user LaunchAgent was disabled in the first place is unknown. Nothing found in the launchd log for it.
  • log in zsh is a shell builtin (prints the watch list), so log show ... fails with too many arguments. Use /usr/bin/log show ..., which is what produced the evidence above.