macOS Chrome Remote Debugging Port 9222 Startup Issues and the Final Solution

Problem Description

When starting Chrome from the command line on macOS with the 9222 remote debugging port enabled, you run into the following problems:

  1. chrome://inspect/#remote-debugging shows the status “Server running at: starting…” and never actually connects
  2. The command line throws: “DevTools remote debugging requires a non-default data directory. Specify this using –user-data-dir.”

Root Cause Analysis

Cause 1: SingletonLock file deadlock

To prevent multiple instances from modifying the same user data directory at the same time, Chrome creates exclusive lock files in the profile directory:

File Purpose
SingletonLock The main lock, indicating whether a process is currently using the directory
SingletonSocket Socket communication lock
SingletonCookie Cookie lock
  • Clean exit (Cmd+Q or kill): Chrome cleans up these lock files itself
  • Force quit (kill -9 or pkill -9): the process is killed hard and has no chance to clean up → on the next launch it detects the leftover lock files, assumes another process is using the directory, and stalls the 9222 port

Cause 2: Chrome security restriction (newer Chrome versions)

Error message: DevTools remote debugging requires a non-default data directory

For security reasons, newer Chrome versions (roughly 2024+) forbid enabling the 9222 remote debugging port on the default user directory (Default Profile). Why?

  • If it were allowed, any local script could take over the browser via the CDP protocol
  • It could silently read passwords, operate a MetaMask wallet, or grab login cookies

Cause 3: A mix of the above

The user passed --profile-directory="Default" but did not specify --user-data-dir, so Chrome tried to connect to the already-running default Chrome main process, and the port got stalled.

Solutions

Option A: Just use a non-default directory (simplest)

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --remote-allow-origins="*" \
  --user-data-dir="$HOME/chrome_dev_data" \
  --no-first-run

If you need to keep your login state, extensions, and so on, use rsync to incrementally sync the default configuration into a dedicated debugging directory.

Step 1: Create the Bash script debug_chrome.sh

#!/bin/bash

SOURCE_DIR="$HOME/Library/Application Support/Google/Chrome/Default"
TARGET_DIR="$HOME/chrome_debug_profile"

echo "正在优雅退出 Google Chrome..."

# 使用 AppleScript 优雅退出,自动清理 SingletonLock
osascript -e 'quit app "Google Chrome"'

# 等待进程完全清理
while pgrep -x "Google Chrome" > /dev/null; do
  sleep 1
done

echo "正在同步配置到调试目录..."

# rsync 增量同步,排除无用缓存,首次慢后续秒级完成
rsync -a --delete \
  --exclude 'Cache' \
  --exclude 'Code Cache' \
  --exclude 'DawnCache' \
  --exclude 'GPUCache' \
  --exclude 'Singleton*' \
  "$SOURCE_DIR/" "$TARGET_DIR/"

echo "正在启动 Chrome 调试模式..."

# 后台静默启动
nohup /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --remote-allow-origins="*" \
  --user-data-dir="$TARGET_DIR" \
  --no-first-run > /dev/null 2>&1 &

echo "✅ 启动成功!可以连接 9222 端口了。"

Step 2: Wrap it as a one-click Mac launch app (Automator)

  1. Open “Automator” → create a new “Application”
  2. Search for “Run Shell Script” and drag it into the workspace on the right
  3. Paste in the Bash script above
  4. Command + S to save it as Chrome Debug.app, and put it in your “Applications” folder
  5. From then on, just double-click Chrome Debug.app to launch everything with one click

Why this script is better

  • Graceful exit via AppleScript → avoids leaving ghost lock files
  • Incremental rsync sync → after the first sync, each run takes seconds, and the bloated cache folders are excluded
  • Isolated environment → messing around in your debugging environment won’t pollute your everyday browsing history
  • One-click launch → wrapped as an app via Automator, so you can keep it in the Dock or trigger it with a shortcut

Diagnostic Commands

# 检查 9222 端口是否被监听
lsof -i tcp:9222

# 检查是否有残留 Chrome Helper 进程
ps aux | grep -i "Google Chrome"

# 手动清理锁文件(如果 AppleScript 无法自动清理)
rm -f ~/Library/Application\ Support/Google/Chrome/SingletonLock
rm -f ~/Library/Application\ Support/Google/Chrome/SingletonSocket
rm -f ~/Library/Application\ Support/Google/Chrome/SingletonCookie

Key Lessons

Action Result
kill -9 / pkill -9 ❌ Process killed hard, lock files left behind → starting…
kill / pkill -15 ✅ Clean exit, lock files cleaned up automatically
AppleScript quit app ✅ The most graceful way to exit
--user-data-dir not specified + --profile-directory="Default" ❌ Chrome’s security restriction refuses debugging
Using a separate --user-data-dir ✅ Bypasses the security restriction

Bottom line: Newer Chrome versions require --user-data-dir to point to a non-default directory. Combining a graceful exit + incremental rsync sync + Automator one-click wrapping is the most elegant way to launch Chrome CDP debugging on macOS.