Replies: 3 comments
|
i tried to set ssr to false and i don't get the error anymore. Do i have to manually refresh the session in a middleware or something like that ? |
|
This error happens when two concurrent server-side requests both detect an expired token and both try to write the Set-Cookie header on the same response object. Nitro routes are stateless but the H3 event object is shared within a single request lifecycle, so if two composables or middleware layers race to refresh the session the second one hits "headers already sent." The fix is to ensure token refresh happens in a single place, typically a server middleware that runs before any route handler: // server/middleware/supabase-session.ts export default defineEventHandler(async (event) => { Calling serverSupabaseClient early in the middleware chain refreshes the token once and sets the cookie before any route handler runs. Subsequent calls to serverSupabaseClient or serverSupabaseUser within the same request reuse the already-refreshed session without trying to write headers again. Also make sure you are not calling serverSupabaseUser inside a parallel Promise.all alongside code that also touches the session, as that can trigger the same race. |
|
This error happens when @supabase/ssr tries to write updated session cookies after the HTTP response headers have already been flushed. The stack trace shows applyServerStorage -> setAll -> setCookie failing because the response is already committed. The most common causes in a Nitro deployment are the following. A server route or middleware that uses the Supabase client but does not await the session check before sending a response. If you send a response (throw createError, return data, or call sendRedirect) before the Supabase client has a chance to flush the updated session cookie, the subsequent cookie write fails. Make sure any code path that ends the request does so after the Supabase client operations are complete. A Supabase client instance that is created outside the request context and shared across requests. The module-provided serverSupabaseClient(event) must be called fresh on each request. If you store the client in a global variable or module-level singleton, the cookie flushing for one request can collide with another. A response hook in your Nitro plugins that sends or modifies the response before the Supabase middleware has run its cleanup. Check your server/plugins directory for any defineNitroPlugin that calls event.node.res.end() or similar. If the error only appears in production and not locally, the difference is usually timing. Production containers handle the response lifecycle faster, which exposes the race condition between response flushing and cookie writing that local dev is slow enough to hide. Adding try-catch around the Supabase utility calls in your routes and logging the timing of the request will usually pinpoint which handler is sending the response too early. |
Uh oh!
There was an error while loading. Please reload this page.
Hi,
i developped a small application using Nuxt supabase module
at first, locally, all worked fine, and the first minutes in production too
but i got a strange ERR_HTTP_HEADERS_SENT error, when (i guess) access_token is out of date and a request is made to refresh it
does someone already encoutered this error ?
i tried to comment all server code that uses access to the authenticated user
i also have no middleware that could interact with the refresh process
i may have done something wrong but i'm out of clue...
My stack is
`[nitro] [unhandledRejection] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
code: 'ERR_HTTP_HEADERS_SENT'
}`
All reactions