vercel/next.js · warning · Error

Failed to set Next.js data cache for ${ctx.fetchUrl || pathn

Error message

Failed to set Next.js data cache for ${ctx.fetchUrl || pathname}, items over 2MB can not be cached (${itemSize} bytes)

What it means

Thrown (in dev) by the incremental cache set when a fetch-cache entry's serialized JSON exceeds 2 MB and no custom cache handler is in use. The 2 MB per-entry cap prevents unbounded cache growth; in production it only warns and skips caching, but in dev it throws to surface the issue early.

Source

Thrown at packages/next/src/server/lib/incremental-cache/index.ts:772

    pathname = this._getPathname(pathname, ctx.fetchCache)

    // FetchCache has upper limit of 2MB per-entry currently
    const itemSize = JSON.stringify(data).length
    if (
      ctx.fetchCache &&
      itemSize > 2 * 1024 * 1024 &&
      // We ignore the size limit when custom cache handler is being used, as it
      // might not have this limit
      !this.hasCustomCacheHandler &&
      // We also ignore the size limit when it's an implicit build-time-only
      // caching that the user isn't even aware of.
      !ctx.isImplicitBuildTimeCache
    ) {
      const warningText = `Failed to set Next.js data cache for ${ctx.fetchUrl || pathname}, items over 2MB can not be cached (${itemSize} bytes)`

      if (this.dev) {
        throw new Error(warningText)
      }
      console.warn(warningText)
      return
    }

    try {
      if (!ctx.fetchCache && ctx.cacheControl) {
        this.cacheControls.set(toRoute(pathname), ctx.cacheControl)
      }

      await this.cacheHandler?.set(pathname, data, ctx)
    } catch (error) {
      console.warn('Failed to update prerender cache for', pathname, error)
    }
  }
}

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Reduce the payload size at the source (server-side pagination, field selection, compression) so the cached body is under 2 MB.
  2. Split the single large fetch into multiple smaller cached fetches.
  3. If you must cache large payloads, implement a custom cache handler (hasCustomCacheHandler bypasses the limit).
  4. Set { cache: 'no-store' } on oversized fetches that shouldn't be cached.

Example fix

// before: caching a >2MB response
const res = await fetch('https://api/all-products', { cache: 'force-cache' })

// after: paginate to keep each cached entry small
const res = await fetch('https://api/products?page=1&limit=100', { cache: 'force-cache' })
Defensive patterns

Strategy: validation

Validate before calling

const MAX = 2 * 1024 * 1024
const data = await res.json()
if (JSON.stringify(data).length > MAX) {
  throw new Error('Cached fetch payload exceeds 2MB; paginate or use no-store')
}

Type guard

function withinFetchCacheLimit(data: unknown): boolean {
  return JSON.stringify(data).length <= 2 * 1024 * 1024
}

Try / catch

try {
  await cache.set(...)
} catch (e) {
  if (e.message.includes('over 2MB')) {
    // re-fetch with no-store or paginate
  }
}

Prevention

When it happens

Trigger: A fetch() returns a very large JSON body that gets cached, and JSON.stringify(data).length > 2*1024*1024. In dev (and not testmode) this throws rather than silently dropping the cache entry.

Common situations: Fetching large API responses (big lists, full dumps) and relying on Next's fetch cache. Aggregating many records into one cached fetch.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/1654759385b37b69. Report an issue: GitHub.