DEV WIKI
프론트엔드 · 오류·증상

Next.js encountered the unstable value Math.random() while prerendering

최종 검토
2026-07-28
참고 자료
있음
관련 기술

빠른 답변

이 오류는 무엇인가요?
prerendering 중 Server Component가 <Suspense> 밖에서 Math.random()을 호출하면 발생하는 Next.js 오류입니다.
가장 흔한 원인은 무엇인가요?
prerendering 중 <Suspense> 밖에서 Math.random()을 호출하지 말고, 값을 요청마다 생성하려면 connection() 또는 io() 뒤로 이동하고, 캐시 가능한 값이면 use cache 함수 안에서 생성하며, 클라이언트 값이면 Client Component에서 생성해야 합니다.
무엇을 먼저 확인해야 하나요?
`next dev`의 오류 오버레이에서 실패한 컴포넌트의 파일 경로와 줄 번호를 확인합니다. 해당 위치가 prerendering 중 호출된 `Math.random()`의 코드 위치를 가리키면 이 오류의 확인 기준에 해당합니다.

현재 증상

  • 애플리케이션 오류 메시지

먼저 확인할 항목

`next dev`의 오류 오버레이에서 실패한 컴포넌트의 파일 경로와 줄 번호를 확인합니다. 해당 위치가 prerendering 중 호출된 `Math.random()`의 코드 위치를 가리키면 이 오류의 확인 기준에 해당합니다.

빌드 결과에서 `next build --debug-prerender`를 실행하고 사용자 코드의 전체 스택 추적을 확인합니다. 스택 추적이 실패한 컴포넌트의 `Math.random()` 호출 위치를 가리키면 해당 오류와 일치합니다.

수정 후 같은 경로를 다시 로드합니다. 의미 있는 화면이 즉시 표시되고 `<Suspense>` fallback이 스트리밍되는 영역만 덮으면 원문이 제시한 검증 상태에 해당합니다.

환경별 원인과 조치

오류 원문

Next.js encountered the unstable value Math.random() while prerendering

의미

prerendering 중 Server Component가 <Suspense> 밖에서 Math.random()을 호출하면 발생합니다. Cache Components가 활성화된 경우 Next.js는 빌드 시점과 실행 시점에 달라지는 예측할 수 없는 값을 prerendered HTML에 포함할 수 없습니다.

확인

  1. next dev에서 오류가 발생한 경로를 엽니다.
  2. 오류 오버레이에서 실패한 컴포넌트의 파일 경로와 줄 번호를 확인합니다.
  3. 빌드 결과를 확인하는 경우 next build --debug-prerender를 실행해 사용자 코드의 전체 스택 추적을 확인합니다.
  4. 특정 경로만 확인하려면 next build --debug-build-paths /dashboard /settings 형식으로 빌드합니다.
  5. 수정 후 경로를 다시 로드하고, 의미 있는 화면이 즉시 표시되는지와 <Suspense> fallback이 스트리밍되는 영역만 덮는지 확인합니다.

수정 방법

요청마다 값 생성

각 요청마다 다른 값이 필요하면 connection() 또는 io() 뒤에서 값을 생성합니다.

import { connection } from 'next/server'export async function RequestTrace() {  await connection()  const traceId = Math.random().toString(16).slice(2)  return <small>trace: {traceId}</small>}

호출 뒤의 컴포넌트를 가장 가까운 <Suspense> 경계로 감싸면 주변 화면은 prerender된 상태로 유지되고 해당 영역만 요청마다 스트리밍됩니다. io()next/cache에서 가져와 사용할 수 있으며 prefetch를 막지 않고 use cache 범위와 Client Component 안에서도 사용할 수 있습니다.

값을 캐시

빌드, 배포 또는 cacheLife 기간 동안 하나의 안정적인 값이면 충분한 경우 Math.random()use cache가 첫 문장인 함수 안으로 이동합니다.

async function getRandomSeed() {  'use cache'  return Math.random()}

캐시 기간을 설정하려면 캐시 함수에서 cacheLife()를 사용합니다. 캐시 기간 동안 모든 방문자가 같은 값을 보게 되므로 사용자별 고유 값이나 보안에 민감한 값에는 사용할 수 없습니다.

클라이언트에서 생성

값이 브라우저 화면에만 필요하면 Client Component로 이동하고, 초기 상태를 결정적인 값으로 설정한 뒤 useEffect에서 실제 무작위 값을 할당합니다.

'use client'import { useEffect, useState } from 'react'export function Avatar() {  const [color, setColor] = useState('#888')  useEffect(() => {    setColor(`#${Math.random().toString(16).slice(2, 8)}`)  }, [])  return <div style={{ background: color }} />}

Client Component의 렌더링 중에 값을 바로 생성하면 SSR 중에도 같은 오류가 발생할 수 있습니다. 서버 HTML에 값이 필요하면 부모의 <Suspense> 경계 안에서 처리해야 합니다.

주의 사항

  • prerender shell에 포함되는 UI는 결정적이어야 합니다. <Suspense> fallback, loading.js, error.js, not-found.js, global-error.js도 포함됩니다.
  • 짧은 cacheLife 프로필의 재검증 시간이 prerender의 유효 기간보다 짧으면 값이 prerender에 포함되지 않고 동적 영역이 될 수 있습니다.
  • 페이지 전체를 하나의 <Suspense> 경계로 감싸 빈 shell만 남기면 검증은 통과할 수 있지만 instant navigation의 목적을 훼손합니다.
  • 요청마다 다른 값이 필요하면 요청마다 생성하는 방법을 사용하고, 캐시 기간 동안 같은 값이면 캐시 방법을 사용하며, 브라우저 화면에만 필요한 값이면 클라이언트 방법을 사용합니다.

관련 오류

Date.now() 및 crypto API도 같은 유형의 prerender 오류를 일으킬 수 있으며, Client Component의 Math.random()은 별도 문서에서 다룹니다.

참고 자료

Next.js encountered the unstable value Math.random() while prerendering | Next.js (새 창에서 열림)

Next.js · 공식 자료 · 확인 범위: Next.js는 prerendering 중 <Suspense> 밖에서 호출된 Math.random() 값을 정적 HTML에 포함할 수 없습니다., 요청마다 다른 값이 필요하면 connection() 또는 io() 뒤에서 Math.random()을 호출할 수 있습니다., 캐시 가능한 값은 use cache 함수 안에서 생성할 수 있습니다., 브라우저에서만 필요한 값은 Client Component의 useEffect 등에서 생성할 수 있습니다., next dev 오류 오버레이는 실패한 컴포넌트의 파일 경로와 줄 번호를 가리킵니다., next build --debug-prerender는 더 자세한 사용자 코드 스택 추적을 제공합니다. · 확인일: 2026-07-28