안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다.
새로운 기능을 완성하고 설레는 마음으로 스프링 부트(Spring Boot) 서버의 실행(Run) 버튼을 마우스로 딱 클릭했습니다. 빌드가 완료되고 로그가 촤르륵 올라가며 서버가 켜지는가 싶더니, 갑자기 시뻘건 에러 로그를 뿜어내며 1초 만에 서버가 툭 꺼져버립니다.
상단에 적힌 강렬한 경고 메시지.
Web server failed to start. Port 8080 was already in use.
분명히 아까까지만 해도 잘 돌아갔는데 왜 갑자기 포트가 이미 사용 중이라는 걸까요?
오늘은 백엔드 개발자라면 누구나 일주일에 한 번씩은 마주치는 '포트 충돌(Port Already in Use) 에러'의 원인을 아주 명쾌한 비유로 알아보고, 윈도우와 맥(Mac) 환경에서 각각 10초 만에 우아하게 해결하는 법까지 확실하게 정리해 드리겠습니다!
1. Port 8080 was already in use, 도대체 넌 누구냐? (2인 1의자 비유)
이 에러는 스프링 부트 웹 서버가 사용하려고 내정한 컴퓨터의 8080번 통로(Port)를 이미 다른 프로그램이 차지하고 있을 때 발생합니다.

네트워크의 세계에서 포트(Port)는 내 컴퓨터로 들어오는 수많은 문(통로)과 같습니다. 스프링 부트의 기본 웹 서버(Tomcat)는 보통 '8080번 문'을 열고 손님을 맞이할 준비를 합니다.
하지만 "한 포트에는 오직 하나의 프로그램만 연결될 수 있다"는 철칙이 있습니다.
만약 이전에 실행했던 스프링 부트가 완전히 꺼지지 않고 좀비(Ghost)처럼 메모리 뒤편에 살아있거나, 오라클(Oracle)이나 다른 프로그램이 이미 8080번 포트를 선점하고 있다면?
새로 켜진 스프링 부트는 8080번 문을 열려다가 "어? 이미 누가 이 문을 쓰고 있네? 나 장사 못 해!"라며 뻗어버리는 것입니다.
2. 해결 방법 ①: 범인(좀비 프로세스) 찾아내서 체포하기 (강제 종료)
가장 정석적이고 실무에서 가장 많이 쓰는 방법입니다. 8080번 포트를 몰래 점유하고 있는 유령 프로세스의 번호(PID)를 조회한 뒤, 강제로 종료시켜 포트를 해방해 주는 것입니다.

내가 쓰는 컴퓨터의 운영체제(OS)에 맞춰 아래의 명령어를 터미널(CMD)에 입력해 보세요.
💻 Windows(윈도우) 환경일 때
- 시작 메뉴에서 CMD(명령 프롬프트)를 검색한 뒤 우클릭 -> 관리자 권한으로 실행합니다.
- 8080 포트를 쓰고 있는 녀석의 주민번호(PID)를 알아내기 위해 아래 명령어를 칩니다.
DOS netstat -ano | findstr 8080 - 결과 화면 맨 우측에 나오는 숫자(예: 12345)가 바로 범인의 PID입니다. 이 숫자를 기억하세요.
- 아래 명령어로 해당 프로세스를 저세상(?)으로 보냅니다. (숫자 부분에 방금 찾은 PID를 넣으세요.)
DOS taskkill /f /pid 12345
🍎 Mac(맥) 환경일 때
- 터미널(Terminal) 앱을 실행합니다.
- 8080 포트를 점유 중인 프로세스를 찾기 위해 아래 명령어를 입력합니다.
Bash lsof -i :8080 - 표의 PID 열에 적힌 숫자(예: 9876)를 확인합니다.
- 아래 명령어로 해당 프로세스를 강력하게 종료시킵니다.
Bash kill -9 9876
프로세스를 종료한 뒤 다시 스프링 부트를 실행해 보면, 거짓말처럼 초록색 로그가 정상적으로 뜨며 서버가 구동될 것입니다!
3. 해결 방법 ②: 내 스프링 부트의 포트 번호 바꾸기
만약 8080 포트를 쓰고 있는 프로그램이 오라클 DB나 다른 중요한 필수 프로그램이라서 종료하면 안 되는 상황이라면 어떻게 해야 할까요?
주인이 비켜주지 않으니, 우리가 비어있는 다른 의자(포트)로 자리를 옮기면 됩니다.

스프링 부트의 설정 파일만 한 줄 수정해 주면 손쉽게 포트를 변경할 수 있습니다.
⚙️ application.properties를 쓰는 경우
프로젝트 안의 src/main/resources/application.properties 파일을 열고 아래 코드를 추가합니다.
Properties
# 💡 기본 8080 대신 8081번 포트로 서버를 열어라!
server.port=8081
⚙️ application.yml을 쓰는 경우
application.yml 파일을 사용 중이라면 아래 구조로 적어줍니다.
YAML
server:
port: 8081
설정 후 서버를 실행하면 콘솔창에 Tomcat initialized with port(s): 8081 (http) 메시지가 뜨며 정상 작동합니다. (단, 브라우저로 접속할 때도 주소창에 http://localhost:8081 로 쳐야 한다는 것을 잊지 마세요!)
4. 요약: 트러블슈팅 체크리스트
Port already in use 에러를 마주했다면 당황하지 말고 아래 3가지를 체크하세요.
- 이전 서버 종료 확인: 혹시 인텔리제이나 이클립스에서 이전 프로젝트를 켜둔 채로 새 프로젝트를 실행하지 않았는지 확인합니다.
- PID 조회 및 강제 종료: 터미널 창을 열어 8080 포트를 물고 있는 PID를 찾고, taskkill 이나 kill -9 명령어로 좀비 프로세스를 사뿐히 즈려밟아 줍니다.
- 포트 변경 검토: 죽일 수 없는 프로그램이 포트를 쓰고 있다면, 쿨하게 server.port=8081 설정을 적용하여 포트를 바꿔서 실행합니다.
마무리
코딩 공부를 시작하고 첫 에러를 만나면 보통 내 코드에 오타가 났거나 로직이 틀린 줄 알고 코드만 뚫어지게 보며 몇 시간씩 낭비하곤 합니다.
하지만 오늘 배운 에러는 컴퓨터 내부의 '자리싸움' 때문에 일어난 단순 네트워크 해프닝일 뿐입니다. 에러 로그가 말해주는 핵심 키워드(Port already in use)만 잘 읽어낸다면, 코드 한 줄 안 고치고도 명령 프롬프트에서 단 10초 만에 해결할 수 있는 아주 귀여운 녀석이죠.
오늘 준비한 트러블슈팅 가이드가 여러분의 실행 창에 기분 좋은 초록색 성공 로그를 띄워주었기를 바랍니다. 오류를 고친 경험은 여러분의 가장 큰 자산이 됩니다. 막히는 에러가 있다면 언제든 댓글로 남겨주세요.
지금까지 데브프리였습니다. 감사합니다!
'💻 트러블슈팅 (에러 해결)' 카테고리의 다른 글
| 기본 생성자가 없다고요? Cannot construct instance of 에러 원인과 1초 해결법 (0) | 2026.07.02 |
|---|---|
| 직원을 뽑은 적이 없는데요? NoSuchBeanDefinitionException 원인과 해결법 완벽 정리 (0) | 2026.07.01 |
| 영원한 JPA의 숙제! LazyInitializationException (no Session) 원인과 해결법 완벽 정리 (0) | 2026.06.30 |
| 데이터 형식 불량! MethodArgumentNotValidException 원인과 해결법 완벽 정리 (0) | 2026.06.29 |
| 분명 데이터를 보냈다는데? HttpMessageNotReadableException 원인과 해결법 완벽 정리 (0) | 2026.06.28 |