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:
chrome://inspect/#remote-debuggingshows the status “Server running at: starting…” and never actually connects- 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 -9orpkill -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
Option B: Clone the default profile (one-click launch script, recommended)
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)
- Open “Automator” → create a new “Application”
- Search for “Run Shell Script” and drag it into the workspace on the right
- Paste in the Bash script above
Command + Sto save it asChrome Debug.app, and put it in your “Applications” folder- From then on, just double-click
Chrome Debug.appto 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-dirto 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.