{"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":null,"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/6beaca39526d5716c3c112ebb0782765baa5a9ce/packages/react-router/lib/server-runtime/sessions/cookieStorage.ts#L38-L72","documentation":"Browsers cap a single cookie at 4096 bytes, and cookie-based sessions (createCookieSessionStorage) must fit the whole session into that one cookie. commitSession (lib/server-runtime/sessions/cookieStorage.ts:56) serializes then measures, and throws with the offending length so you find out at commit time instead of silently losing the session in the browser.","triggerScenarios":"session.set() with large objects (user profiles, tokens, arrays, base64 blobs); flash messages accumulating without unset; growing key sets over a long-lived session; encrypted cookies where the signature/ciphertext inflates the payload.","commonSituations":"Storing OAuth/JWT payloads or whole API responses in the session; e-commerce carts kept in the session cookie; forgetting session.unset() after reading flash data.","solutions":["Store only small identifiers (userId, flags) in the cookie session and keep bulky data server-side","Switch to a server-backed session storage (DatabaseSessionStorage or a custom SessionStorage keyed by session id)","unset() flash/single-use keys right after reading them in the loader","Audit session.data contents and remove keys you no longer write"],"exampleFix":"// before\nsession.set('user', user) // whole profile -> >4KB after signing\n// after\nsession.set('userId', user.id)\n// load the rest from the DB in the loader","handlingStrategy":"validation","validationCode":"// Check size before committing\nconst serialized = await cookie.serialize(session.data);\nif (serialized.length > 4096) {\n  // trim or move to server-side storage before commitSession\n  session.unset(' bulkyKey');\n}\nconst setCookie = await commitSession(session);","typeGuard":null,"tryCatchPattern":"try {\n  return json(data, { headers: { 'Set-Cookie': await commitSession(session) } });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('browser maximum')) {\n    // drop non-essential keys and retry once\n    session.unset('flash');\n    return json(data, { headers: { 'Set-Cookie': await commitSession(session) } });\n  }\n  throw e;\n}","preventionTips":["Keep only ids/flags in cookie sessions; store payloads server-side keyed by session id","unset() flash and one-time keys immediately after reading","Unit-test session size for your largest realistic payloads","Use DatabaseSessionStorage once data exceeds a few hundred bytes"],"tags":["session","cookie","storage","size-limit","commit-session"],"backgroundTag":"cookie-size-limit","analyzedSha":"6beaca39526d5716c3c112ebb0782765baa5a9ce","analyzedAt":"2026-08-18T18:04:14.938Z","contentChangedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}