{"record":{"id":"17573490aa65f297","repo":"remix-run/react-router","slug":"cookie-length-will-exceed-browser-maximum-length","errorCode":null,"errorMessage":"Cookie length will exceed browser maximum. Length: ${serializedCookie.length}","messagePattern":"Cookie length will exceed browser maximum\\. Length: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router/lib/server-runtime/sessions/cookieStorage.ts","lineNumber":56,"sourceCode":"  Data,\n  FlashData\n> {\n  let cookie = isCookie(cookieArg)\n    ? cookieArg\n    : createCookie(cookieArg?.name || \"__session\", cookieArg);\n\n  warnOnceAboutSigningSessionCookie(cookie);\n\n  return {\n    async getSession(cookieHeader, options) {\n      return createSession(\n        (cookieHeader && (await cookie.parse(cookieHeader, options))) || {},\n      );\n    },\n    async commitSession(session, options) {\n      let serializedCookie = await cookie.serialize(session.data, options);\n      if (serializedCookie.length > 4096) {\n        throw new Error(\n          \"Cookie length will exceed browser maximum. Length: \" +\n            serializedCookie.length,\n        );\n      }\n      return serializedCookie;\n    },\n    async destroySession(_session, options) {\n      return cookie.serialize(\"\", {\n        ...options,\n        maxAge: undefined,\n        expires: new Date(0),\n      });\n    },\n  };\n}\n","sourceCodeStart":38,"sourceCodeEnd":72,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router/lib/server-runtime/sessions/cookieStorage.ts#L38-L72","documentation":"`createCookieSessionStorage().commitSession` serializes all session data into the cookie and rejects when the serialized cookie exceeds 4096 bytes (the practical browser cookie limit). Cookie-session storage trades backend-free simplicity for a hard size cap; exceeding it would silently truncate the session in the browser.","triggerScenarios":"Calling `commitSession(session)` on a session whose serialized form (data + cookie name + options like `Max-Age`, `Path`, signed HMAC for secret cookies) is over 4096 bytes.","commonSituations":"Storing growing per-user data (flash messages, cart contents, JSON blobs) in the session; stacking multiple flash messages; a signed cookie where the HMAC signature alone consumes hundreds of bytes; adding many cookie options that bloat the header.","solutions":["Move large/per-user data to a server-side store and keep only a session id in the cookie (use `createSessionStorage` with a custom adapter backed by Redis/DB).","Clear flash data before commit and trim unused fields.","Reduce cookie options (long `SameSite`, `Domain`, etc.) and shorten the cookie name.","If you need signed cookies, account for the signature size in your 4096 budget."],"exampleFix":"// before\nexport const sessionStorage = createCookieSessionStorage({ cookie: { name: '__session' } });\n// session.data grows until > 4096 bytes -> throws on commit\n\n// after\nexport const sessionStorage = createSessionStorage({\n  cookie: { name: 'sid', secrets: ['...'] },\n  createData: (data, expires) => redis.set(...),\n  readData: (id) => redis.get(id),\n  updateData: (id, data, expires) => redis.set(...),\n  deleteData: (id) => redis.del(id),\n});","handlingStrategy":"validation","validationCode":"async function safeCommit(storage: SessionStorage, session: Session, max = 4096) {\n  const cookie = await storage.commitSession(session);\n  if (cookie.length > max) throw new Error(`Cookie too large: ${cookie.length}`);\n  return cookie;\n}\n// or, proactively estimate before commit:\nfunction estimateCookieBytes(data: unknown) {\n  return JSON.stringify(data).length + 200; // +overhead/signature headroom\n}","typeGuard":null,"tryCatchPattern":"try {\n  headers.append('Set-Cookie', await sessionStorage.commitSession(session));\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Cookie length will exceed')) {\n    // spill to server-side store, keep only an id in the cookie\n    session.id = await persist(session.data);\n    session.data = {};\n    headers.append('Set-Cookie', await sessionStorage.commitSession(session));\n  } else throw e;\n}","preventionTips":["Keep only an id in cookie-session storage; back large data with Redis/DB via `createSessionStorage`.","Clear flash messages before commit.","Account for the signature bytes when using signed cookies."],"tags":["sessions","cookies","cookie-storage","size-limit"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}