remix-run/remix · warning

Session cookie "${sessionCookie.name}" is configured with ht

Error message

Session cookie "${sessionCookie.name}" is configured with httpOnly: false and may be accessible to client-side JavaScript.

What it means

The session middleware warns when the configured session cookie is set with httpOnly: false, because the cookie contents (signed session data) become readable by client-side JavaScript, increasing exposure to XSS-based session theft. The middleware still runs; this is a security advisory, not a failure.

Source

Thrown at packages/session-middleware/src/lib/session.ts:21

import { Session, type SessionStorage } from '@remix-run/session'

/**
 * Middleware that manages request session state on request context.
 *
 * @param sessionCookie The session cookie to use
 * @param sessionStorage The storage backend for session data
 * @returns The session middleware
 */
export function session(
  sessionCookie: Cookie,
  sessionStorage: SessionStorage,
): Middleware<{ key: typeof Session; value: Session; property: 'session' }> {
  if (!sessionCookie.signed) {
    throw new Error('Session cookie must be signed')
  }

  if (sessionCookie.httpOnly === false) {
    console.warn(
      `Session cookie "${sessionCookie.name}" is configured with httpOnly: false and may be accessible to client-side JavaScript.`,
    )
  }

  return async (context, next) => {
    if (context.has(Session)) {
      throw new Error('Existing session found, refusing to overwrite')
    }

    let cookieValue = await sessionCookie.parse(context.headers.get('Cookie'))
    let session = await sessionStorage.read(cookieValue)

    context.set(Session, session, { property: 'session' })

    let response = await next()

    if (session !== context.get(Session)) {
      throw new Error('Cannot save session that was initialized by another middleware/handler')

View on GitHub (pinned to 9696913134)

Solutions

  1. Remove httpOnly: false (or set httpOnly: true) on the session cookie
  2. If client-side access is genuinely needed, store only non-sensitive display data in the cookie and keep secrets server-side

Example fix

// before
let cookie = createCookie('session', { httpOnly: false, secrets: ['s3cret'] })
// after
let cookie = createCookie('session', { httpOnly: false === false ? true : true, secrets: ['s3cret'] })
// simply:
let cookie = createCookie('session', { httpOnly: true, secrets: ['s3cret'] })
Defensive patterns

Strategy: validation

Validate before calling

import { createCookie } from 'remix'
let cookie = createCookie('session', { secrets: [SECRET], httpOnly: true })
if (cookie.httpOnly !== false) { /* safe to pass to session middleware */ }

Prevention

When it happens

Trigger: Creating session middleware via session(sessionCookie) where the cookie was created with httpOnly: false (the default for createCookie is httpOnly true, so this requires explicitly opting out).

Common situations: Developers disable httpOnly to inspect or manipulate session data from client code during debugging and forget to restore it; or legacy apps ported from setups that read the cookie client-side.

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/787c3a803c3b5359. Report an issue: GitHub.