mastra-ai/mastra · error · HTTPException
Session expired
Error message
Session expired
What it means
This HTTP 401 error is thrown when `auth.refreshSession(sessionId)` resolves to null/undefined — the provider recognized the session ID but could not renew it, typically because the session expired server-side or no longer exists.
Source
Thrown at packages/server/src/server/handlers/auth.ts:633
if (
!auth ||
!implementsInterface<ISessionProvider>(auth, 'refreshSession') ||
!implementsInterface<ISessionProvider>(auth, 'getSessionIdFromRequest')
) {
throw new HTTPException(404, { message: 'Session refresh not configured' });
}
// Get session ID from request
const sessionId = auth.getSessionIdFromRequest(request);
if (!sessionId) {
throw new HTTPException(401, { message: 'No session' });
}
// Refresh the session
const newSession = await auth.refreshSession(sessionId);
if (!newSession) {
throw new HTTPException(401, { message: 'Session expired' });
}
// Build response with new session headers
const headers = new Headers({ 'Content-Type': 'application/json' });
if (implementsInterface<ISessionProvider>(auth, 'getSessionHeaders')) {
const sessionHeaders = auth.getSessionHeaders(newSession);
for (const [key, value] of Object.entries(sessionHeaders)) {
headers.append(key, value);
}
}
return new Response(JSON.stringify({ success: true }), {
status: 200,
headers,
});
} catch (error) {
if (error instanceof HTTPException) throw error;
return handleError(error, 'Error refreshing session');View on GitHub (pinned to 75dd419e61)
Solutions
- Treat 401 as sign-out: redirect the user to the sign-in flow to establish a fresh session.
- Refresh sessions proactively before TTL expiry rather than after; increase session/refresh TTL in provider config if appropriate.
- If sessions vanish on deploy, use a persistent session store instead of in-memory.
Example fix
// before const res = await refreshSession(); // throws 401 after expiry // after const res = await refreshSession(); if (res.status === 401) redirectToSignIn();
Defensive patterns
Strategy: fallback
Validate before calling
// optionally track last-refresh time client-side and refresh before typical TTL const REFRESH_INTERVAL_MS = 10 * 60 * 1000; if (Date.now() - lastRefreshAt > REFRESH_INTERVAL_MS) scheduleRefresh();
Try / catch
try {
const res = await fetch('/api/auth/session/refresh', { method: 'POST', credentials: 'include' });
if (res.status === 401) {
await signInAgain(); // session expired: full re-auth
}
} catch (e) { redirectToSignIn(); } Prevention
- Refresh tokens proactively on a timer or on user activity, before expiry.
- Never retry refresh in a loop on 401 — it will always fail once the session is dead.
- Use a persistent session store server-side so deploys don't invalidate sessions.
When it happens
Trigger: POST the session refresh endpoint with a session ID that the provider cannot refresh: expired beyond the refresh window, revoked, or deleted from the session store.
Common situations: User idle past session TTL; server restarted with an in-memory session store losing all sessions; refresh attempted after absolute expiry (refresh tokens only renew within limits).
Related errors
- ${validationResult.error || 'invalid_token'}
- No session
- Authentication required
- ${errorData.message || 'Invalid email or password'}
- Invalid email or password
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1d0cb285c12786f7.
Report an issue: GitHub.