# macOS에 숨어있던 49일짜리 시한폭탄 — TCP 네트워킹이 완전히 멈추는 커널 버그 전말

> Clean Markdown view of GeekNews topic #28312. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=28312](https://news.hada.io/topic?id=28312)
- GeekNews Markdown: [https://news.hada.io/topic/28312.md](https://news.hada.io/topic/28312.md)
- Type: news
- Author: [darjeeling](https://news.hada.io/@darjeeling)
- Published: 2026-04-08T14:26:33+09:00
- Updated: 2026-04-08T14:26:33+09:00
- Original source: [photon.codes](https://photon.codes/blog/we-found-a-ticking-time-bomb-in-macos-tcp-networking)
- Points: 20
- Comments: 9

## Summary

macOS를 **정확히 49일 17시간 2분 47초** 연속 가동하면 TCP 네트워킹이 완전히 멈추는 커널 버그가 발견되었습니다. 원인은 `tcp_now` 카운터의 **32비트 정수 오버플로우**로, 커널의 TCP 시계가 멈추면서 TIME_WAIT 연결이 영원히 회수되지 않는 구조입니다. ping은 되는데 새 TCP 연결이 안 되는 증상이라 디버깅이 까다롭고요. Mac 서버를 장기간 재부팅 없이 운영하는 분이라면 꼭 확인해두세요. 현재 유일한 해결책은 **재부팅**이라고 합니다. 근데 댓글에도 보면 정작 발생하는 사람이 많지는 않기도 한 것 같아요. **제가 최근에 맥북을 서버로 하나 이용중인데.. 49일 후에 말씀드리겠습니다.**

## Topic Body

macOS XNU 커널에서 **정확히 49일 17시간 2분 47초** 연속 가동 후 TCP 네트워킹이 완전히 마비되는 버그가 발견됐다. 원인은 커널 내부 TCP 타임스탬프 카운터(`tcp_now`)의 **32비트 정수 오버플로우**다. ping은 계속 응답하지만 새로운 TCP 연결은 전혀 맺을 수 없게 되며, 현재 유일한 해결책은 재부팅이다.  
  
---  
  
#### 발견 경위  
  
Photon은 iMessage 서비스 상태를 모니터링하는 Mac 서버 플리트를 24/7 운용하고 있었다. 2026년 3월 30일, 마지막 재부팅으로부터 정확히 49.7일이 지난 시점에 여러 머신이 조용히 새 TCP 연결을 거부하기 시작했다. ping은 정상, 기존 연결도 유지됐지만 **새 소켓을 여는 모든 시도가 실패**했다.  
  
서비스를 복구하기 위해 재부팅 후, 팀은 며칠 내로 같은 임계점에 도달할 머신 두 대(A, B)를 골라 **라이브 실험**을 설계했다.  
  
---  
  
#### 버그의 기술적 원리  
  
##### 문제의 카운터 `tcp_now`  
  
XNU 커널의 `tcp_now`는 부팅 이후 경과 시간을 **밀리초 단위로 세는 32비트 부호 없는 정수**다. 32비트가 표현할 수 있는 최댓값은 4,294,967,295ms — 이를 환산하면 정확히 49일 17시간 2분 47초다.  
  
##### 왜 카운터가 "얼어붙는"가?  
  
`tcp_now` 업데이트 코드에는 "시계가 뒤로 가지 않도록" 하는 단순한 가드가 있다:  
  
```c  
if (tmp < current_tcp_now) {  
    os_atomic_cmpxchg(&tcp_now, tmp, current_tcp_now, ...);  
}  
```  
  
오버플로우 순간, 새로 계산된 `current_tcp_now`는 0 근처로 다시 감기지만, 기존 `tmp`는 최댓값 근처에 있다. 조건 `tmp < current_tcp_now`가 **영원히 false**가 되어 `tcp_now`는 그 값에 그대로 멈춰버린다. **커널의 TCP 시계가 멈춘 것이다.**  
  
##### TIME\_WAIT가 만료되지 않는 이유  
  
TCP 연결이 닫힐 때 커널은 만료 시각을 `tcp_now + 30초`로 기록해둔다. 주기적으로 가비지 컬렉터가 스캔하며 `tcp_now >= 만료시각`이면 연결을 해제한다. 그런데 `tcp_now`가 얼어버리면 이 조건이 **절대 참이 되지 않아** TIME\_WAIT 연결이 영영 회수되지 않는다.  
  
---  
  
#### 실험 결과  
  
팀은 오버플로우 전후 각 5분씩 초당 여러 건의 단명 TCP 연결을 생성하며 TIME\_WAIT 수를 관찰했다.  
  
| 구간 | 상태 |  
|---|---|  
| 오버플로우 전 | TIME\_WAIT가 ~200개에서 안정적으로 유지 (30초마다 정상 만료) |  
| 오버플로우 직후 | 만료가 멈추고 TIME\_WAIT 단조 증가 시작 |  
| 연결 생성 중단 84초 후 | 0이 되어야 할 TIME\_WAIT가 오히려 **증가** (2,828 → 2,837) |  
| 오버플로우 후 9.5시간 | Machine A: **4,888개**, Machine B: **8,217개** — 단 한 건도 회수 안 됨 |  
  
9.5시간 후에는 SYN\_SENT 상태 연결도 3,000개 이상 쌓이고, Machine B의 로드 애버리지가 **49.74**까지 치솟았다.  
  
---  
  
#### 영향을 받는 환경  
  
일반 소비자 Mac은 OS 업데이트로 49일 이전에 재부팅하는 경우가 많아 영향이 적다. 하지만 다음 환경은 고위험군이다:  
  
- 장시간 무중단 서버 플리트  
- macOS CI/CD 빌드 서버 (Jenkins, GitHub Actions 셀프호스트 러너)  
- Mac Pro 워크스테이션 (렌더링·컴파일 장시간 실행)  
- 원격 관리 코로케이션 Mac  
- Mac mini 빌드팜·테스트 인프라  
  
---  
  
#### 현재 및 향후 대응  
  
팀은 현재 재부팅 없이 동결된 `tcp_now`를 직접 수정하는 워크어라운드를 개발 중이다. 그 전까지의 임시 대책은 하나다:  
  
> **49일 17시간 2분 47초 이전에 재부팅을 스케줄링하라.**  
  
---  
  
#### 유사한 역사적 버그들  
  
이 버그는 유구한 계보를 가진 정수 오버플로우 버그군에 속한다: Windows 95/98의 49.7일 크래시, 2038년 문제(Y2K38), GPS 주차 번호 롤오버, 팩맨 256스테이지 킬스크린이 모두 같은 계열이다.  
  
---  
  
*원문: [Photon Blog, 2026.04.07](https://photon.codes/blog/we-found-a-ticking-time-bomb-in-macos-tcp-networking)*

## Comments



### Comment 54921

- Author: brilliant08
- Created: 2026-04-08T14:36:25+09:00
- Points: 8

요즘은 MacOS 가 49제를 다 지내는군요

### Comment 55164

- Author: bungker
- Created: 2026-04-13T09:14:13+09:00
- Points: 1
- Parent comment: 54921
- Depth: 1

ㅋㅋㅋㅋㅋㅋ

### Comment 54945

- Author: roxie
- Created: 2026-04-09T00:06:52+09:00
- Points: 1
- Parent comment: 54921
- Depth: 1

zzzzz

### Comment 54923

- Author: devil1032
- Created: 2026-04-08T16:36:12+09:00
- Points: 3

시간 이슈라고 하니까 Y2K가 생각나는군요.. 🤖..

### Comment 54952

- Author: savvykang
- Created: 2026-04-09T08:22:07+09:00
- Points: 2

인간은 같은 실수를 반복합니다

### Comment 54985

- Author: shincad
- Created: 2026-04-09T18:45:42+09:00
- Points: 1

49일이전에 정말로 재부팅을 해야 하는군요.  
  
이게 사실 시간은 절대 < 로 비교하면 안되는건데..  
  
if ((int32_t)(tmp - current_tcp_now) < 0) {  
        os_atomic_cmpxchg(&tcp_now, tmp, current_tcp_now, ...);  
}  
이렇게 해서 두 값의 차이를 봐야 하는 건데... 인간은 항상 같은 실수를 하게 되네요.

### Comment 54953

- Author: icosahedron
- Created: 2026-04-09T09:36:32+09:00
- Points: 1

이런거 보면 2038년에 진짜 난리날지도 모르겠네요

### Comment 54944

- Author: princox
- Created: 2026-04-08T22:58:53+09:00
- Points: 1

와 이거 정말 말도 안되네요....

### Comment 54932

- Author: jic5760
- Created: 2026-04-08T18:29:13+09:00
- Points: 1

AWS 나 github 의 mac instance 들은 어떻게 그동안 문제가 없었던거죠...?
