2026. 7. 18.
`No Cache Detected`는 언제 무시해도 될까? Next.js CI는 두 번째 빌드로 판단합니다
Next.js CI의 No Cache Detected가 첫 빌드라 정상인지 반복 누락인지 가르고, .next/cache의 restore와 save를 두 번의 빌드 로그로 검증하는 순서다.

CI 로그에 No Cache Detected가 보여도 첫 빌드라면 앱 코드를 고칠 일은 아니다. Next.js 공식 오류 문서는 새 프로젝트나 CI의 첫 실행에서는 이 경고를 무시할 수 있다고 설명한다. 다만 두 번째 성공 빌드에서도 같은 경고가 반복되면 .next/cache가 실행 사이에 이어지는지 점검해야 한다.
완료 기준은 경고 한 줄을 숨기는 것이 아니다. 첫 실행에서 캐시를 저장하고, 다음 실행에서 같은 경로나 이전 키의 캐시가 복원되는 로그를 확인한다. 두 번의 성공 실행이 있어야 첫 빌드와 반복 누락을 구분할 수 있다.
첫 빌드는 통과시키고, 같은 경고가 반복되면 설정을 본다
첫 실행에는 복원할 이전 캐시가 없다. 이때 cache miss와 No Cache Detected가 함께 보이는 것은 자연스럽다. 먼저 빌드가 끝까지 성공하는지 확인한다. 실패한 작업은 새 캐시를 남기지 못할 수 있으므로, 경고보다 실제 build 오류를 먼저 해결한다.
두 번째 실행부터는 질문이 달라진다.
| 실행 | 기대할 증거 | 다음 판단 |
|---|---|---|
| 첫 성공 빌드 | cache miss 뒤 save 또는 새 cache 생성 로그 | 같은 브랜치에서 한 번 더 실행 |
| 두 번째 성공 빌드 | exact hit 또는 restore key를 통한 복원 로그 | .next/cache가 복원됐는지 확인 |
| 매번 miss | 경로, 키, 브랜치 범위, 작업 성공 여부 중 하나 점검 | 앱 코드가 아니라 CI 설정 수정 |
첫 빌드 한 번만 보고 캐시 설정의 성공과 실패를 판정하지 않는다. 경고가 반복될 때만 restore 단계가 실제 경로와 키를 찾지 못한 이유를 좁힌다.
.next/cache를 restore와 save 사이에 둔다
Next.js CI Build Caching 가이드는 Next.js가 빌드 사이에 공유할 캐시를 .next/cache에 저장한다고 설명한다. GitHub Actions 예제는 actions/cache@v4의 경로에 npm 캐시와 ${{ github.workspace }}/.next/cache를 함께 둔다.
핵심 구조는 아래와 같다.
- uses: actions/cache@v4
with:
path: |
~/.npm
${{ github.workspace }}/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
경로에는 **실제 빌드가 만드는 .next/cache**가 들어가야 한다. 모노레포라면 앱 폴더가 저장소 루트와 다를 수 있으므로 ${{ github.workspace }}/apps/web/.next/cache처럼 실제 위치에 맞춘다. 캐시 step은 npm run build보다 앞에 있어야 복원된 파일을 빌드가 사용할 수 있다.
키는 모든 실행에서 무조건 같게 만들지 않는다. 공식 예제처럼 운영체제, lockfile, 소스 변화를 반영한 정확한 키를 만들고, 소스만 달라졌을 때 이전 dependency 계열 캐시를 이어받도록 restore-keys를 둔다. package-lock이 예상과 다르면 CI 설치 결과도 흔들릴 수 있으므로 package-lock과 npm ci가 어긋날 때 점검하는 순서도 함께 본다.
cache-hit 한 줄보다 restore와 save 로그를 두 번 비교한다
GitHub Actions 캐시 공식 문서는 정확한 key가 일치할 때 cache-hit가 true가 된다고 설명한다. 정확한 키가 없더라도 restore-keys의 접두사가 맞으면 최근 캐시가 부분 복원될 수 있다. 따라서 cache-hit: false 한 줄만으로 캐시가 전혀 없었다고 단정하지 않는다.
다음 네 줄을 두 실행에서 기록한다.
- cache step이 계산한 최종 key
- exact hit인지 restore key 부분 일치인지
- build가 성공했는지
- 작업 끝에 새 cache가 저장됐는지
첫 실행의 save와 다음 실행의 restore가 한 쌍이다. 첫 실행이 실패했거나 save 전에 취소됐다면 다음 실행은 복원할 새 캐시가 없다. 두 실행의 runner OS, 브랜치, path가 달라져도 같은 현상이 난다.
반복 miss는 경로, 키, 성공 종료 순서로 좁힌다
경고가 계속되면 아래 순서로 한 변수씩 확인한다.
- 빌드 후 실제
.next/cache폴더가 생겼는지 본다. - cache step의
path가 모노레포 앱 위치와 일치하는지 본다. - 첫 실행과 둘째 실행의 key 접두사와 lockfile hash가 어떻게 달라졌는지 비교한다.
- 작업이 성공 종료돼 cache save 단계까지 도달했는지 본다.
- feature branch에서 default branch 캐시를 복원할 수 있는 범위와 반대 방향을 혼동하지 않았는지 공식 문서로 확인한다.
캐시에 토큰이나 비밀 파일을 넣지 않는다. GitHub 문서는 캐시 경로의 민감정보를 피하라고 경고한다. .next/cache와 패키지 관리자 캐시에 필요한 빌드 산출물만 두고, .env나 자격 증명 경로를 추가하지 않는다.
커스텀 webpack 설정 때문에 빌드 방식이 달라졌다면 Next.js 16에서 custom webpack과 Turbopack을 가르는 기준처럼 번들러 설정을 먼저 확정한다. 캐시는 정상인데 빌드 자체가 매번 다른 경로를 쓰면 비교 결과가 흐려진다.
오늘 남길 결과는 연속된 두 성공 로그에서 save와 restore가 연결된 증거다. 경고가 사라지지 않아도 restore 경로와 키가 확인됐다면 그 로그를 기준으로 Next.js 문서의 현재 동작과 비교할 수 있다.
참고 출처
CI 서비스와 Next.js의 캐시 동작은 바뀔 수 있으므로 적용 전 공식 문서와 최신 릴리스 노트를 함께 확인한다.
다음으로 읽을 기사
같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.
첫 번째 댓글을 남겨보세요
여러분의 생각이 다른 독자에게 도움이 됩니다.
댓글 0
이 글을 읽은 독자들의 생각을 나눠보세요.