본문으로 바로가기

FastAPI 서버 연결 거부 오류 10061 해결 순서

결론부터 말하면, Windows 소켓 오류 10061은 요청을 보낸 주소와 포트에서 연결을 받아 주는 서버가 없거나 연결이 거부됐다는 뜻이다. FastAPI 코드의 응답 내용보다 먼저 서버 프로세스와 TCP 바인딩을 확인해야 한다.

가장 빠른 순서는 ① Uvicorn 프로세스가 살아 있는지, ② 실제로 어느 주소와 포트를 듣는지, ③ 클라이언트 URL이 같은지, ④ Docker라면 포트가 호스트에 공개됐는지 확인하는 것이다.

2026-08-22에 일회성 Linux 컨테이너에서 FastAPI 0.141.1과 Uvicorn 0.52.4를 실행했다. 서버 시작 전 8000번은 연결 거부, 시작 후 /health는 HTTP 200, 서버가 없는 8001번은 다시 연결 거부였다. Linux 오류 번호는 111이었으며 Windows 전용 숫자 10061을 직접 실행했다고 주장하지 않는다.

이 글로 해결할 수 있는 것

  • 10061이 HTTP 404·500과 다른 단계의 오류임을 구분한다.
  • 프로세스, 바인딩 주소, 포트와 Docker 공개 순서로 검사한다.
  • 수정 후 health endpoint로 확인한다.

실행 환경과 증거

  • python:3.12-slim 일회성 컨테이너
  • Python 3.12.14, FastAPI 0.141.1, Uvicorn 0.52.4
  • 증거: content/evidence/fastapi_connection_refused_20260822.json
  • 시험 컨테이너는 실행 후 제거

1. 프로세스가 실제로 시작됐는지 본다

python -m uvicorn app:app --host 127.0.0.1 --port 8000

터미널에 traceback이 나오고 프로세스가 끝났다면 포트 검사보다 import·문법·환경변수 오류를 먼저 해결한다. 실행 로그의 URL은 브라우저에 표시할 장식이 아니라 실제 바인딩 단서다.

2. 주소와 포트를 확인한다

같은 PC에서만 접근한다면 127.0.0.1로 충분하다. 다른 PC나 Docker 호스트에서 접근해야 한다면 서버가 컨테이너 내부 loopback에만 묶여 있지 않은지 확인하고 필요한 경우 --host 0.0.0.0을 사용한다. 0.0.0.0은 브라우저 목적지 주소가 아니라 모든 인터페이스에서 듣겠다는 바인딩 값이다.

3. 실제 재현 결과를 비교한다

상태요청결과
서버 시작 전127.0.0.1:8000/health연결 거부
8000에서 실행 중127.0.0.1:8000/healthHTTP 200, {"status":"ok"}
잘못된 포트127.0.0.1:8001/health연결 거부

서버가 응답한 뒤의 404는 라우트 경로 문제이고 500은 애플리케이션 내부 오류다. 10061은 그보다 앞선 연결 단계에서 실패한 상태다.

4. Docker 포트를 확인한다

docker ps --format "table {{.Names}}\t{{.Ports}}"
docker logs --tail 100 <container-name>

컨테이너 안에서 8000을 듣더라도 -p 8000:8000 또는 Compose의 ports가 없으면 호스트의 8000으로 접근할 수 없다. 호스트 포트가 이미 사용 중이면 컨테이너가 시작 단계에서 실패했을 수 있다.

5. 수정 후 health로 확인한다

curl -i http://127.0.0.1:8000/health

프로세스가 살아 있다는 사실만으로 의존 서비스까지 정상인 것은 아니다. 최소 health는 HTTP 상태와 짧은 JSON을 반환하고, 필요하면 DB·큐 같은 의존성 점검을 별도 readiness로 나눈다.

한계

Windows 방화벽, 백신, 프록시와 WSL 네트워크는 이 Linux 격리 실행에서 재현하지 않았다. Windows 10061의 의미는 Microsoft Winsock 문서를 근거로 하고, 실행 증거는 같은 TCP 연결 거부 상태의 진단 순서를 확인하는 데 한정한다.

출처와 변경 이력