V2Ray 로그 확인 방법: 주요 오류 원인과 단계별 해결법

로그 레벨과 출력 위치를 살펴보고 연결 시간 초과, 핸드셰이크 실패, 포트 충돌, 인증서 오류 등 자주 발생하는 문제의 원인과 단계별 점검 순서를 안내합니다.

핵심 내용

‘클라이언트는 실행됐는데 웹페이지가 열리지 않는’ 경우에 유용한 안내입니다. 클라이언트 로그와 코어 로그를 구분한 뒤 로컬 리스닝, 라우팅 규칙, 도메인 확인, 원격 연결, 프로토콜 핸드셰이크 순으로 점검합니다. 오류 메시지 예시와 포트 확인 명령, 재테스트 방법도 소개합니다. 설정은 한 번에 하나씩만 바꿔 포트, DNS, 노드 매개변수가 뒤섞이지 않도록 하세요.

1. 로그 위치 확인: 클라이언트 메시지와 코어 오류는 다릅니다

v2rayN은 그래픽 클라이언트이며, 실제 연결은 선택한 코어가 처리하는 경우가 일반적입니다. 안드로이드용 v2rayNG는 Xray 코어를, v2flyNG는 V2Fly 코어를 사용합니다. 클라이언트는 구독, 설정 생성, 프로세스 관리를 담당하고 코어는 리스닝, 라우팅, 트래픽 전달을 담당합니다. 따라서 ‘구독 다운로드 실패’와 ‘서버 연결 시간 초과’는 서로 다른 로그에 기록될 수 있습니다. 창에 마지막으로 표시된 메시지만 보고 노드가 작동하지 않는다고 판단하지 마세요.

v2rayN에서는 먼저 메인 창의 로그나 정보 영역을 확인한 다음, ‘설정’ → ‘매개변수 설정’에서 현재 버전이 제공하는 로그 레벨과 로그 기록 옵션을 찾아보세요. 데스크톱 UI와 버전에 따라 메뉴 이름과 구성은 다를 수 있으므로 모든 버전에 같은 버튼이 있다고 가정하면 안 됩니다. 안드로이드에서는 클라이언트의 로그 화면에서 연결 과정을 확인하세요. 현재 화면에 간략한 메시지만 표시된다면 사용할 수 있는 코어 로그나 내보내기 기능도 살펴보세요.

2. 로그 레벨과 재현 방법: 요청 한 번을 처음부터 끝까지 기록하기

V2Ray와 Xray에서 자주 쓰이는 오류 로그 레벨은 debug, info, warning, error, none입니다. 우선 info로 연결 과정을 확인하고, 정보가 부족할 때만 잠시 debug를 켠 뒤 문제를 재현하고 원래 설정으로 되돌리세요. 접속 로그는 별도로 출력 여부를 설정하는 경우가 많으며, 오류 로그를 debug로 바꿔도 반드시 표시되는 것은 아닙니다.

  1. 현재 클라이언트 이름, 실제 사용 중인 코어, 노드 프로토콜, 프록시 모드, 로컬 리스닝 포트를 기록하고 노드는 아직 변경하지 마세요.
  2. 테스트를 시작한 시간을 기록하고, 계속 새로고침되는 웹페이지와 백그라운드 다운로드를 종료해 관련 없는 연결을 줄이세요.
  3. 코어를 재시작해 로그 설정을 적용한 뒤, 확인된 대상 하나에 한 번만 접속해 보세요.
  4. 같은 시간대의 오류 로그 전체를 확보하고, 바깥쪽의 ‘처리 실패’보다 가장 안쪽에 기록된 구체적인 원인을 먼저 확인하세요.
  5. 한 가지 요인만 바꾼 뒤 같은 요청을 다시 실행하고, 오류가 ‘로컬에서 거부됨’에서 ‘원격 연결 시간 초과’ 등 다른 단계로 바뀌는지 비교하세요.

아래는 코어 JSON 로그의 일부로, 각 항목을 이해하기 위한 예시이며 완전한 설정이 아닙니다. 그래픽 클라이언트를 사용한다면 클라이언트 설정에서 조정하는 것이 좋습니다. 자동 생성된 실행 설정을 직접 수정하면 노드를 바꾸거나 재시작할 때 덮어써질 수 있습니다.

{
  "log": {
    "loglevel": "info"
  }
}

3. 가까운 단계부터 점검: 요청이 어느 단계까지 도달했는지 확인하기

앱 요청 로컬 리스닝 라우팅 규칙 적용 주소 확인 원격 연결 프로토콜 핸드셰이크

이 흐름은 문제를 점검하기 위한 모델이며 모든 설정이 반드시 이 순서로 처리되는 것은 아닙니다. 예를 들어 라우팅 규칙이 먼저 DNS 조회를 유발할 수 있고, 프록시 서버 도메인과 대상 사이트 도메인이 서로 다른 경로로 확인될 수도 있습니다. 중요한 것은 ‘앱에서 로컬 클라이언트로’, ‘클라이언트에서 프록시 서버로’, ‘프록시 서버에서 대상 사이트로’ 이어지는 세 구간을 구분하는 것입니다.

웹에 접속했는데 관련 로그가 전혀 없다면 앱이 시스템 프록시를 따르는지, 로컬 주소를 우회하는지, 현재 로그가 접속을 기록하는지부터 확인하세요. 시스템 프록시는 해당 설정을 따르는 앱에만 영향을 줍니다. 시스템 프록시를 켜도 모든 프로그램의 트래픽이 자동으로 코어를 통과하는 것은 아닙니다. TUN 모드는 가상 인터페이스, 권한, 라우팅도 관련되므로 별도로 확인하세요. 여러 트래픽 가로채기 방식을 동시에 켜면 원인을 파악하기 어려워질 수 있습니다.

10808
이 문서의 로컬 SOCKS 테스트 포트
443
이 문서의 원격 TLS 포트 예시
15초
이 문서에서 단일 요청에 적용하는 최대 대기 시간

위 내용은 진단을 위한 예시일 뿐 모든 클라이언트에서 같은 포트를 사용해야 한다는 뜻은 아닙니다. 매개변수 설정에서 실제 인바운드 프로토콜과 포트를 먼저 확인하세요. 10808에서 SOCKS 인바운드를 제공하지 않는다면 아래 명령을 그대로 사용할 수 없습니다. Windows 터미널에서는 curl.exe, macOS 터미널에서는 curl을 사용하세요.

curl.exe --proxy socks5h://127.0.0.1:10808 --connect-timeout 5 --max-time 15 -I https://example.com/

socks5h는 대상 도메인의 확인을 SOCKS 프록시에서 처리하도록 합니다. 다만 프록시 서버 자체의 도메인은 로컬에서 확인해야 할 수 있습니다. HTTP 응답을 받았다면 해당 요청이 적어도 대상 서비스까지 도달한 것입니다. 거부 응답이나 오류 상태 코드가 반환됐더라도 이를 곧바로 프록시 연결 실패와 같은 의미로 보면 안 됩니다.

4. 포트 충돌과 연결 거부: 로컬 진입점부터 해결하기

오류: bind: address already in use

원인: 코어가 리스닝하려는 주소와 포트를 다른 프로세스가 이미 사용 중입니다. Windows에서는 ‘Only one usage of each socket address’라는 메시지가 표시되기도 합니다.

해결: 포트를 사용 중인 프로세스를 확인하고, 중복 실행된 클라이언트를 정상 종료하거나 로컬 리스닝 포트를 변경한 뒤 앱의 프록시 설정도 함께 업데이트하세요.

오류: connect: connection refused

원인: 연결이 명시적으로 거부됐습니다. 해당 주소에서 서비스가 리스닝하지 않을 때 흔히 발생합니다. 방화벽이 연결을 거부했을 수도 있으므로 오류에 표시된 대상 주소부터 확인해야 합니다.

해결: 대상이 127.0.0.1이면 로컬 코어와 포트를 확인하세요. 원격 서버가 대상이라면 서버의 리스닝 포트와 인바운드 규칙을 점검하세요.

Windows에서는 먼저 로컬 10808의 리스닝 정보를 조회한 다음, 출력된 PID로 프로세스를 확인하세요. 포트가 사용 중이라고 알 수 없는 시스템 프로세스를 종료하지 마세요. 다른 클라이언트가 실행 중인지 먼저 확인해야 합니다.

netstat -ano -p tcp | findstr ":10808"
tasklist /FI "PID eq 1234"

두 번째 명령의 1234는 예시 PID입니다. 첫 번째 명령의 출력에서 실제 프로세스 번호를 확인해 바꾸고 상태가 LISTENING인지 살펴보세요. macOS에서는 lsof -nP -iTCP:10808 -sTCP:LISTEN으로 리스닝 중인 프로세스를 확인할 수 있습니다. 포트를 변경했다면 코어를 재시작한 뒤 앞서 안내한 단일 요청 테스트를 다시 실행하세요.

5. 연결 시간 초과와 주소 확인 실패: 주소 문제와 네트워크 문제 구분하기

오류: dial tcp: lookup …: no such host

원인: 연결하려는 도메인에서 사용할 수 있는 주소를 확인하지 못했습니다. 오류에 표시된 도메인은 프록시 서버일 수도, 대상 웹사이트일 수도 있습니다.

해결: 도메인 철자와 구독 정보를 확인하고 해당 요청에 어떤 DNS 확인기가 사용됐는지 살펴보세요. 먼저 프록시 서버 주소가 확인되는지 테스트한 다음 대상 웹사이트의 DNS 경로를 점검하세요.

오류: dial tcp …: i/o timeout

원인: 정해진 시간 안에 연결을 완료하지 못했습니다. 네트워크 연결 불가, 패킷 손실, 방화벽의 패킷 차단, 원격 서비스의 무응답 등이 원인일 수 있습니다.

해결: 오류에 표시된 주소와 포트가 예상한 노드의 것인지 확인한 뒤 같은 노드로 네트워크를 바꿔 테스트하세요. 여러 네트워크에서 모두 실패한다면 서버 관리자에게 리스닝 상태와 접근 규칙을 확인해 달라고 요청하세요.

오류: context deadline exceeded

원인: 작업이 제한 시간을 넘겼다는 뜻입니다. 이 메시지만으로는 구독 다운로드, DNS 조회, 프록시 연결 중 어느 단계에서 발생했는지 알 수 없습니다.

해결: 앞뒤 로그를 확인해 작업 대상을 먼저 파악한 뒤 구독 주소와 노드 연결을 각각 테스트하세요. 모든 시간 초과 오류를 노드 문제로 단정하지 마세요.

Windows에서는 nslookup example.com으로 시스템의 주소 확인 결과를 볼 수 있습니다. 다만 이는 현재 시스템 확인기의 동작만 보여 줄 뿐, 코어 설정에서 사용하는 DNS 경로도 정상이라는 뜻은 아닙니다. 원격 포트는 PowerShell의 Test-NetConnection으로 테스트할 수 있습니다. 아래 예시 도메인을 노드의 실제 서버 주소로 바꾸세요.

Test-NetConnection -ComputerName node.example.net -Port 443

TcpTestSucceeded가 참이면 TCP 연결이 성공했다는 뜻일 뿐 VMess, VLESS, TLS, REALITY 핸드셰이크까지 성공했다는 의미는 아닙니다. 반대로 일반 TCP 테스트만으로 다른 전송 방식의 모든 경우를 확인할 수도 없습니다. DNS를 ‘우회’하겠다며 서버 주소를 임의의 IP로 바꾸면 TLS 이름 불일치 같은 문제가 새로 생길 수 있습니다.

6. 인증서 오류와 핸드셰이크 실패: 가장 안쪽의 원인부터 확인하기

오류: x509: certificate has expired or is not yet valid

원인: 현재 시간이 인증서 유효 기간에 포함되지 않습니다. 기기의 시간이 잘못됐거나 서버 인증서가 만료됐을 수 있습니다.

해결: 먼저 시스템 자동 시간 설정을 켜고 날짜가 정확한지 확인하세요. 시간이 맞는데도 오류가 계속되면 서버에서 인증서를 갱신하고 새 인증서가 실제 서비스에 적용됐는지 확인해야 합니다.

오류: x509: certificate signed by unknown authority

원인: 인증서 신뢰 체인을 구성하지 못했습니다. 서버의 인증서 체인이 불완전하거나, 인증서를 교체하는 네트워크 장비를 통해 연결됐을 수 있습니다.

해결: 서버 인증서 체인과 기기의 신뢰 설정을 확인하고 필요하면 네트워크를 바꿔 다시 테스트하세요. 원인을 찾는 대신 인증서 검증을 끄지 마세요.

오류: tls: handshake failure

원인: TLS 협상이 거부됐거나 완료되지 않았습니다. 잘못된 서비스에 연결했거나 서버 이름이 일치하지 않거나 양쪽 TLS 설정이 호환되지 않을 수 있습니다.

해결: 서버 설정과 비교해 주소, 포트, 서버 이름, 전송 설정을 확인하세요. 호환성이 확인된 설정 조합으로 먼저 되돌린 다음 항목별로 테스트하세요.

오류: EOF / connection reset by peer

원인: 상대방이 연결을 종료하거나 재설정했습니다. 전송, 핸드셰이크, 정상적인 연결 종료 과정에서 발생할 수 있으며, 이 메시지만으로 인증 정보가 잘못됐다고 판단할 수는 없습니다.

해결: 오류가 발생한 시점과 앞뒤 상황을 함께 확인하고 프로토콜 및 전송 설정을 점검하세요. 같은 시각의 서버 로그도 확인해야 합니다.

VMess와 VLESS의 인증 정보, 전송 설정, 보안 계층 매개변수는 서버 설정과 일치해야 합니다. WebSocket 경로, Host, TLS 서버 이름은 서로 다른 항목입니다. 모두 도메인처럼 보인다는 이유로 같은 값으로 바꾸지 마세요. VMess에서는 시스템 시간도 중요하므로 먼저 시간을 동기화한 뒤 계속 점검하세요.

7. 구독, 분할 라우팅, 일부 사이트 오류: 자주 묻는 질문

구독 업데이트는 시간 초과되지만 기존 노드는 작동합니다. 노드를 바꿔야 하나요?

먼저 노드를 바꾸지 마세요. 구독 업데이트는 클라이언트가 구독 서버에 접속하는 작업으로, 노드 테스트와는 다릅니다. 구독 주소가 유효한지 확인하세요. 클라이언트에 ‘프록시를 통해 업데이트’ 기능이 있다면 기존 노드가 작동할 때 해당 기능을 켜고 다시 시도할 수 있습니다. 구독 주소를 프록시 서버 주소인 것처럼 노드 설정에 입력하지 마세요.

속도 테스트는 정상이지만 브라우저에서 웹페이지가 열리지 않습니다. 무엇부터 확인해야 하나요?

먼저 브라우저 요청이 로컬 리스닝에 도달하는지 확인한 뒤 어떤 아웃바운드가 선택됐는지 살펴보세요. 속도 테스트는 지연 시간이나 특정 대상만 확인할 수 있으므로 브라우저 요청도 같은 경로를 통과한다고 볼 수 없습니다. 이 문서의 SOCKS 포트를 명시한 명령으로 다시 테스트하면 시스템 프록시 설정에 따른 혼란을 줄일 수 있습니다.

일부 웹사이트만 연결되지 않습니다. DNS 문제인가요, 라우팅 분할 문제인가요?

접속에 성공한 대상 하나와 실패한 대상 하나를 기록하고, 같은 시간대의 대상 도메인, 확인된 주소, 아웃바운드 태그를 비교하세요. 실패한 요청이 직접 연결로 분류됐다면 규칙 순서를 먼저 확인하세요. 프록시를 거쳐도 실패한다면 주소 확인, 핸드셰이크, 대상 서비스의 응답을 살펴보세요. 모든 규칙을 바로 지우지는 마세요.

로그에 warning이 계속 표시됩니다. debug를 계속 켜 둬야 하나요?

그럴 필요는 없습니다. 해당 경고가 실제 실패한 요청과 관련 있는지 먼저 확인하세요. 브라우저가 연결을 취소하거나 백그라운드에서 상태를 확인하는 과정에서도 로그가 남을 수 있습니다. debug를 잠시 켜고 한 번 재현한 뒤 원래 레벨로 되돌리세요. 접속 기록이 포함된 이전 로그는 필요에 따라 삭제하세요.

8. 문의를 남기기 전: 재현에 필요한 최소한의 기록 준비하기

문제 해결의 목표는 로그에서 빨간 메시지를 모두 없애는 것이 아니라 어느 구간에서 실패하는지, 어떤 변경으로 결과가 일정하게 달라지는지 확인하는 것입니다. 로컬 리스닝이 정상이고 서버 주소를 확인할 수 있으며 TCP 연결도 된다면 클라이언트를 반복해서 재설치하기보다 프로토콜과 핸드셰이크를 점검하세요. 로컬 리스닝 자체가 없다면 시작 실패와 포트 충돌부터 해결해야 합니다.

  1. 환경: 운영체제 종류, 실제 사용 중인 클라이언트 및 코어 버전, 시스템 프록시 또는 TUN 모드 사용 여부.
  2. 설정 정보: 프로토콜 이름, 전송 방식, TLS 또는 REALITY 사용 여부. 인증 정보는 공개하지 않아도 됩니다.
  3. 재현 방법: 테스트 시각, 사용한 로컬 포트, 요청 대상, 오류를 꾸준히 재현할 수 있는지 여부.
  4. 비교 결과: 네트워크를 바꾸거나 정상 작동이 확인된 다른 노드를 사용하거나 기존 설정으로 되돌렸을 때 달라진 결과.
  5. 로그 맥락: 요청 시작부터 오류가 끝날 때까지의 일부 로그를 민감 정보가 드러나지 않게 정리해 공유하세요. 마지막 줄의 ‘연결 실패’만 올리면 원인을 파악하기 어렵습니다.
v2rayN 다운로드데스크톱 및 안드로이드 클라이언트