오류 메시지 해석: address already in use가 왜 발생하는가
Clash와 Clash Meta(mihomo) 커널 기반 클라이언트는 실행될 때 설정 파일에 지정된 여러 포트를 감시(listen)하려고 시도합니다. HTTP와 SOCKS5 요청을 동시에 받는 믹스 포트(mixed-port), 별도의 HTTP 포트(port)와 SOCKS5 포트(socks-port)가 그 예이며, 일부 클라이언트는 추가로 RESTful API 포트(external-controller, 기본값은 대개 9090)도 사용합니다. 이 중 어느 하나라도 시스템의 다른 프로세스가 이미 점유하고 있다면 커널은 바인딩(bind) 단계에서 실패하고, 로그나 팝업에 다음과 같은 메시지가 나타납니다.
panic: listen tcp 127.0.0.1:7890: bind: address already in use
이 오류 메시지는 상황을 명확히 알려줍니다. 커널이 7890 포트를 감시하려 했지만, 해당 포트가 이미 다른 프로세스에 "선점"되어 운영체제가 이를 거부한 것입니다. 이는 설정 파일 문법 오류도, 구독이나 노드 문제도 아니라 순수하게 로컬 포트 자원이 충돌하는 문제입니다. 해결 순서는 항상 동일합니다: 먼저 포트를 점유한 프로세스를 찾고, 그 프로세스를 "종료할지" 아니면 "Clash가 다른 포트를 쓰게 할지"를 결정하면 됩니다.
Clash 계열 클라이언트를 두 개 이상 설치하고(예: Clash Verge Rev와 ClashX Meta) 둘 다 부팅 시 자동 실행으로 설정했다면, 거의 반드시 기본 포트를 서로 점유하게 됩니다. 이런 경우에는 포트를 계속 바꾸기보다 그중 하나를 제거하거나 자동 실행을 끄는 것이 우선입니다.
Windows: netstat와 PowerShell로 포트 점유 프로세스 찾기
Windows에서 가장 직접적인 방법은 명령 프롬프트나 PowerShell을 열어 netstat로 포트에 연결된 프로세스 ID(PID)를 확인한 뒤, 작업 관리자나 taskkill로 역추적해 종료하는 것입니다. 기본값인 7890 포트를 예로 들면 다음과 같습니다.
netstat -ano | findstr :7890
출력의 마지막 열이 PID입니다. 예를 들어 12480이 표시되었다면 다음을 실행합니다.
tasklist | findstr 12480
이렇게 하면 어떤 실행 파일이 해당 포트를 점유하고 있는지 확인할 수 있습니다. 종료해도 문제없는 프로세스라고 판단되면 바로 종료할 수 있습니다.
taskkill /PID 12480 /F
PowerShell 사용자는 명령 한 줄로 포트에 대응하는 프로세스 이름을 바로 확인할 수 있어 더 직관적입니다.
Get-Process -Id (Get-NetTCPConnection -LocalPort 7890).OwningProcess
흔한 점유 원인으로는 이전에 Clash 클라이언트가 비정상 종료된 뒤 남은 백그라운드 프로세스(특히 작업 관리자로 창만 강제로 닫고 커널 프로세스는 종료되지 않은 경우), 다른 Clash 커널 기반 도구, 그리고 일부 다운로드 도구나 로컬 프록시 디버깅 도구가 기본적으로 7890 근처 포트 대역을 사용하는 경우 등이 있습니다.
macOS: lsof로 포트 점유 확인하기
macOS에서 가장 많이 쓰이는 방법은 lsof(list open files)로, 포트 번호로 점유 프로세스를 역추적할 수 있습니다.
sudo lsof -i :7890
출력에서 COMMAND 열은 프로세스 이름, PID 열은 프로세스 번호입니다. 확인 후 프로세스를 종료합니다.
kill -9 해당PID
netstat에 익숙하다면 macOS에도 호환되는 형태가 남아 있지만, 정보가 더 완전한 lsof 사용을 권장합니다. 또한 ClashX, ClashX Meta처럼 메뉴 바 기반 클라이언트는 메뉴 바 아이콘을 종료해도 백그라운드의 핵심 프로세스가 함께 종료되지 않는 경우가 있으므로, 포트 충돌이 발생했다면 화면만 닫은 게 아니라 핵심 프로세스가 실제로 종료되었는지 먼저 확인해야 합니다.
ps aux | grep -i clash
이 명령어로 현재 시스템에서 clash와 관련된 모든 프로세스를 한 번에 나열해 남은 인스턴스를 정리할 수 있습니다.
Linux: ss와 fuser로 프로세스 찾고 종료하기
최신 배포판에서는 점차 사용이 줄고 있는 netstat 대신 ss를 사용하는 것이 권장됩니다.
sudo ss -tulnp | grep 7890
출력 중 users:(("프로세스명",pid=1234,...)) 부분이 점유 정보입니다. 더 간단하게는 fuser로 바로 찾아서 종료할 수도 있습니다.
sudo fuser -k 7890/tcp
이 명령어는 7890 포트를 점유한 프로세스를 즉시 종료합니다. 점유 주체가 안전하게 종료해도 되는 이전 프로세스임을 확인했을 때 사용하기 적합합니다. systemd로 mihomo나 clash 서비스를 관리하고 있다면, 먼저 서비스 인스턴스가 두 개 동시에 실행되고 있는지 확인하는 것이 더 안전합니다.
systemctl status mihomo
systemctl status clash
두 서비스가 모두 실행 중이고 같은 포트를 동시에 감시하려 한다면, 포트를 바꿔서 "우회"하기보다 그중 하나를 비활성화해야 합니다. 그렇지 않으면 규칙, 구독 업데이트 등의 기능이 두 프로세스에 분산되어 상태가 불일치하고, 오히려 문제 파악이 더 어려워집니다.
Clash 설정 파일에서 믹스 포트 변경하기
포트를 점유한 프로그램을 쉽게 종료할 수 없는 경우(예: 시스템 서비스거나 계속 사용해야 하는 다른 도구), Clash 쪽 감시 포트를 바꾸는 편이 더 간단합니다. Clash Meta(mihomo) 커널에서는 믹스 포트 필드를 직접 사용하는 것을 권장합니다.
mixed-port: 7895
allow-lan: false
bind-address: "*"
external-controller: 127.0.0.1:9096
secret: ""
mixed-port 값을 기본값인 7890에서 점유되지 않은 포트로 바꾸면 됩니다(10000 이상, 일반 소프트웨어와 충돌하지 않는 번호대를 권장합니다. 예: 7895, 17890 등). 저장 후 클라이언트를 재시작하면 적용됩니다. 만약 mixed-port가 아니라 예전 방식의 port(HTTP)와 socks-port(SOCKS5) 필드를 함께 사용한다면, 이 필드들도 충돌 여부를 함께 확인해야 합니다.
port: 7891
socks-port: 7892
external-controller: 127.0.0.1:9097
external-controller(RESTful API 포트, 기본값은 대개 9090)도 별도의 포트를 점유합니다. Clash 패널(Dashboard)이 열리지 않고 오류 메시지에 7890이 아닌 9090이 나온다면 원리와 해결 방법은 동일하며, 다만 수정할 필드만 다릅니다.
대부분의 그래픽 클라이언트(Clash Verge Rev, Clash Plus, FlClash 등)도 설정 화면에서 포트 번호를 직접 입력할 수 있는 항목을 제공하며, 이는 설정 파일의 해당 필드를 수정하는 것과 동일한 효과를 냅니다. 수정 후에도 커널이나 클라이언트를 재시작해야 적용됩니다. 포트를 바꾼 뒤에는 시스템 프록시 설정이나 브라우저 확장 프로그램에 입력된 포트 번호도 함께 업데이트해야 합니다. 그렇지 않으면 "클라이언트는 정상 작동하지만 브라우저는 여전히 연결되지 않는" 상황이 발생하는데, 이는 포트 충돌 자체의 문제가 아니라 포트를 바꾼 뒤 시스템 프록시가 따라가지 못한 것입니다.
흔한 점유 원인과 예방 방법
사용자들의 피드백을 정리해 보면, 7890 근처 포트 대역에서 가장 흔한 충돌 원인은 다음 몇 가지입니다. 미리 알아두면 확인 과정을 한 번 줄일 수 있습니다.
- 이전 Clash 프로세스가 완전히 종료되지 않음: 창 오른쪽 위 닫기 버튼만 눌러도 핵심 프로세스는 백그라운드에서 계속 실행 중일 수 있어, 다시 실행하면 자기 자신과 포트를 놓고 경쟁하게 됩니다.
- 여러 Clash 계열 클라이언트를 동시에 설치: 예를 들어 컴퓨터에 Clash Verge Rev와 예전 버전의 Clash for Windows 잔여 파일이 함께 남아 있고, 둘 다 자동 실행으로 설정되어 있으면 충돌이 쉽게 발생합니다.
- 기타 프록시/디버깅 도구: 일부 로컬 개발용 디버깅 프록시 도구나 패킷 캡처 도구도 기본적으로 7890이나 그 근처 포트를 사용합니다.
- 컨테이너나 가상화 환경의 포트 포워딩: Docker나 가상 머신에서 포트 매핑을 사용할 때, 컨테이너 내부 서비스가 호스트의 포트에 매핑되면서 마침 이 구간과 겹치는 경우가 있습니다.
예방 방법은 간단합니다. 실제로 사용 중인 Clash 계열 클라이언트는 하나만 남기고 나머지 자동 실행 항목은 제거하거나 완전히 비활성화하세요. 여러 프록시 도구를 동시에 병행해야 한다면, 오류가 난 뒤 즉흥적으로 포트를 바꾸기보다 미리 각 도구마다 겹치지 않는 포트 구간을 계획해 두는 것이 좋습니다.
자주 묻는 질문
포트를 바꿨는데도 클라이언트가 여전히 포트가 점유되었다고 알리는 이유는?
먼저 설정 파일이 저장된 경로와 클라이언트가 실제로 불러오는 설정 파일이 동일한지 확인하세요. 일부 클라이언트는 여러 프로필 전환을 지원하므로, 수정한 파일이 현재 적용 중인 프로필이 아닐 수 있습니다. 또한 새로 입력한 포트가 마침 다른 서비스와 또 충돌하고 있는지도 확인해야 합니다. 좀 더 흔치 않은 4자리나 5자리 포트로 바꿔 다시 시도하고, 앞서 소개한 명령어로 그 포트가 비어 있는지 다시 확인해 보세요.
포트를 점유한 프로세스를 종료해도 안전한가요? 시스템에 영향이 없나요?
점유 주체가 남아 있던 Clash 프로세스거나 다시 실행할 수 있는 일반 애플리케이션이라면 종료해도 안전합니다. 하지만 lsof/netstat 결과에서 점유 주체가 시스템 수준 서비스나 낯선 프로세스로 나온다면, 먼저 해당 프로세스 이름을 검색해 용도를 확인하거나, 시스템 서비스를 잘못 종료하는 것을 피하기 위해 차라리 Clash 쪽 포트를 바꾸는 것을 권장합니다.
모바일(Android/iOS)에서도 포트 점유 문제가 발생하나요?
모바일 샌드박스 정책은 훨씬 엄격해서, 포트 충돌은 주로 VPN/프록시 앱을 여러 개 동시에 실행할 때 발생합니다. 시스템은 보통 한 번에 하나의 VPN 설정만 활성화되도록 허용합니다. 연결이 실패한다면 다른 프록시 앱이 백그라운드에서 VPN 서비스를 실행하고 있는지 먼저 확인하고, 그중 하나를 끄면 해결됩니다. 처리 방식은 데스크톱보다 훨씬 단순합니다.