이 글에서 정리하는 내용
Vercel 404 NOT_FOUND는 배포가 실패했다는 뜻만은 아닙니다. 배포는 성공했지만 요청 URL이 Next.js 라우트, rewrites, basePath, 동적 경로, output 설정과 맞지 않을 때도 같은 화면이 나옵니다.
라우팅 문제가 redirect 설정과 연결되어 있다면 Next.js redirects 설정 방법에서 next.config.js 기준 URL 이동 처리 방식을 먼저 확인하세요.
이 글은 프론트엔드 배포 오류 체크리스트: Vercel, Vite, Expo 문제 해결의 세부 항목입니다. 전체 설정 흐름과 관련 오류 해결 순서는 대표 허브 글에서 함께 확인할 수 있습니다.
- 내 증상이 이거면 여기부터 보세요
- 먼저 적용할 핵심 수정 코드
- 왜 이런 오류가 생기는가
- 실제 작업에서 점검하는 순서
- 그래도 안 될 때 볼 예외 케이스
- 다음에 같은 문제를 줄이는 체크리스트
내 증상이 이거면 여기부터 보세요

Vercel 배포 후 첫 화면은 열리는데 특정 URL만 404가 나거나, 로컬에서는 되는데 배포에서만 NOT_FOUND가 보이면 라우팅과 배포 설정을 같이 봐야 합니다. 특히 App Router, rewrites, basePath가 섞이면 원인이 흐려집니다.
| 증상 | 실제 에러 메시지 | 먼저 볼 위치 | 바로 해볼 조치 | 이동할 섹션 |
|---|---|---|---|---|
| 특정 경로만 404 | 404: NOT_FOUND | app/pages 라우트 | 파일 기반 라우트와 URL 대조 | 핵심 수정 코드 |
| rewrite 후 404 | The page could not be found | vercel.json rewrites | source/destination 확인 | 핵심 수정 코드 |
| 프로젝트 루트가 다름 | No Output Directory | Vercel root/build 설정 | Root Directory와 framework preset 확인 | 예외 케이스 |
| 동적 페이지가 배포에서만 실패 | NOT_FOUND dynamic route | generateStaticParams | fallback/동적 렌더링 설정 확인 | 왜 생기는가 |
오류 해결 글에서는 실제 에러 문구가 본문에 있어야 검색해서 다시 찾기 쉽습니다. 프로젝트명, 사용자명, 토큰, 절대 경로처럼 민감하거나 불필요한 값은 빼고 대표 문구만 남깁니다.
404: NOT_FOUND
The page could not be found
This Serverless Function has crashed
No Output Directory named "dist" found after the Build completed
먼저 적용할 핵심 수정 코드
원인 설명을 오래 읽기 전에 아래 설정부터 현재 코드와 대조해보세요. 먼저 Vercel 배포 로그에서 빌드 성공 여부를 확인하고, 실제 요청 URL이 Next.js app/pages 라우트와 일치하는지 대조합니다. 중요한 것은 오류를 덮는 옵션을 추가하는 것이 아니라, 실행 환경과 설정 파일이 같은 기준으로 동작하게 만드는 것입니다.
vercel.json rewrites 예시
{
"rewrites": [
{
"source": "/blog/:slug",
"destination": "/posts/:slug"
}
]
}
source는 사용자가 접근하는 URL, destination은 실제 Next.js 라우트입니다. 둘을 반대로 쓰면 404가 납니다.
Next.js app 라우트 구조 대조
app/
page.tsx -> /
blog/
[slug]/
page.tsx -> /blog/my-post
api/health/
route.ts -> /api/health
배포 URL이 이 구조와 맞는지 먼저 확인하면 rewrites 문제인지 라우트 문제인지 분리됩니다.
왜 이런 오류가 생기는가
Vercel의 404 NOT_FOUND는 요청을 처리할 페이지나 함수가 없을 때 나타납니다. 빌드 자체가 성공했더라도 사용자가 접근한 경로가 실제 산출물에 없으면 404가 나옵니다.
Next.js App Router는 폴더 구조가 URL이 됩니다. route group 괄호 폴더는 URL에 포함되지 않고, page.tsx가 있는 폴더만 페이지가 됩니다. 로컬에서 dev 서버가 관대하게 보이던 문제가 배포에서 명확하게 드러날 수 있습니다.
rewrites는 URL을 바꿔 보여주는 기능이지만 없는 목적지로 보내면 404를 해결하기보다 숨깁니다. rewrite를 추가하기 전에 실제 destination 라우트가 존재하는지 확인해야 합니다.
실제 작업에서 점검하는 순서
첫 번째로 오류가 나온 단계를 나눕니다. 개발 서버에서만 보이는지, 빌드에서 실패하는지, 배포나 CI에서만 실패하는지에 따라 봐야 할 파일이 달라집니다. 같은 메시지라도 실행 위치가 다르면 원인도 다를 수 있습니다.
두 번째로 한 번에 여러 설정을 바꾸지 않습니다. Vercel 404 NOT_FOUND 오류를 해결하다 보면 관련 파일을 전부 고치고 싶어지지만, 그러면 어떤 변경이 실제 해결책이었는지 알기 어렵습니다. 핵심 설정 하나를 바꾸고 검증 명령을 실행한 뒤 다음 설정으로 넘어가야 합니다.
세 번째로 저장소에 남는 기준으로 정리합니다. 개인 PC에서만 통과하는 임시 조치가 아니라 설정 파일, 패키지 버전, 배포 설정처럼 팀원이 같은 기준으로 재현할 수 있는 형태가 되어야 합니다.
그래도 안 될 때 볼 예외 케이스
기본 수정 후에도 같은 메시지가 남는다면 캐시, 버전 차이, 경로 대소문자, 실행 위치를 같이 봐야 합니다. 오류 메시지는 하나처럼 보여도 실제로는 개발 서버, 타입 검사, 번들러, 배포 환경이 서로 다른 설정을 읽어서 생기는 경우가 많습니다.
- basePath를 쓰는 프로젝트는 로컬 URL과 배포 URL 앞부분이 달라질 수 있습니다.
- monorepo에서는 Vercel Root Directory가 앱 폴더를 가리키는지 확인합니다.
- 정적 export 설정을 쓰면 서버 기능이나 동적 라우트가 기대와 다르게 동작할 수 있습니다.
다음에 같은 문제를 줄이는 체크리스트

Vercel 404는 배포 실패, 라우트 누락, rewrite 실수, 프로젝트 루트 설정이 같은 화면으로 보입니다. 그래서 배포 로그와 실제 파일 기반 라우트를 먼저 대조한 뒤 rewrite와 basePath를 보는 순서가 안전합니다.
- 배포 로그에서 build 성공 여부를 확인합니다.
- 요청 URL과 app/pages 라우트 구조를 대조합니다.
- vercel.json rewrites의 source/destination을 확인합니다.
- monorepo라면 Root Directory와 Output 설정을 확인합니다.
결국 Vercel 404 NOT_FOUND 오류는 한 줄짜리 우회 코드보다 확인 순서가 중요합니다. 에러 문구를 단계별로 나누고, 설정 파일과 실행 명령을 같은 기준으로 맞추면 같은 문제를 훨씬 짧게 끝낼 수 있습니다.