nextauthjs/next-auth · error
[updateSession] Failed to fetch updated session
Error message
[updateSession] Failed to fetch updated session
What it means
Firebase adapter's updateSession writes the updated session document with Firestore, then immediately re-reads it with getDoc to return the fresh record. If the re-read returns nothing, it concludes the update did not land and throws this error. It usually means the session document was deleted (or never matched the given sessionToken) between or during the update, or Firestore connectivity/permission issues caused a silent write/read mismatch.
Source
Thrown at packages/adapter-firebase/src/index.ts:217
mapper.toDb("sessionToken"),
"==",
partialSession.sessionToken
)
.limit(1)
)
).docs[0]
if (!sessionSnapshot?.exists) return null
transaction.set(sessionSnapshot.ref, partialSession, { merge: true })
return sessionSnapshot.id
})
if (!sessionId) return null
const session = await getDoc(C.sessions.doc(sessionId))
if (session) return session
throw new Error("[updateSession] Failed to fetch updated session")
},
async deleteSession(sessionToken) {
await deleteDocs(
C.sessions
.where(mapper.toDb("sessionToken"), "==", sessionToken)
.limit(1)
)
},
async createVerificationToken(verificationToken) {
await C.verification_tokens.add(verificationToken)
return verificationToken
},
async useVerificationToken({ identifier, token }) {
const verificationTokenSnapshot = (
await C.verification_tokensView on GitHub (pinned to a1a16a5a77)
Solutions
- Verify the session document actually exists in Firestore for the given sessionToken before/while calling updateSession
- Ensure deleteSession/expiry cleanup is not racing updateSession (single-tab logout, transactional deletes)
- Check Firestore security rules and service-account permissions allow both write and read of the sessions collection
- Clear the stale session cookie on the client and force a fresh sign-in flow
- Check network/Firestore status if this occurs fleet-wide
Example fix
// before
await adapter.updateSession({ sessionToken: staleToken, expires: new Date() })
// after
const existing = await adapter.getSessionAndUser(staleToken)
if (existing) {
await adapter.updateSession({ sessionToken: staleToken, expires: new Date() })
} Defensive patterns
Strategy: try-catch
Validate before calling
const snap = await getDoc(doc(db, 'sessions', sessionToken))
if (!snap.exists()) {
// refresh session cookie / force sign-in instead of updating
} Type guard
function sessionExists(s: any): s is { sessionToken: string; expires: Date } {
return !!s && typeof s.sessionToken === 'string'
} Try / catch
try {
await adapter.updateSession({ sessionToken, expires })
} catch (e) {
if ((e as Error).message.includes('Failed to fetch updated session')) {
await signOut({ redirect: false }) // dead session
} else throw e
} Prevention
- Check session existence before updating
- Avoid racing logout and session refresh across tabs
- Audit Firestore rules for read/write on the sessions collection
- Clear cookies when the session document is gone
When it happens
Trigger: Calling updateSession with a sessionToken whose document no longer exists in Firestore (expired/deleted session), concurrent deleteSession racing updateSession, or Firestore rules/permissions causing the getDoc re-read to return an empty snapshot.
Common situations: Users logging out in one tab while another tab triggers a session refresh; clock-skew-driven expiry jobs deleting sessions; misconfigured Firestore security rules blocking reads for the adapter's service account; returning an already-deleted token from a stale client cookie.
Related errors
- [updateUser] Failed to fetch updated user
- [createSession] Failed to fetch created session
- [createUser] Failed to fetch created user
- [updateUser] Missing id
- Session not found
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/cb96af9533d82d60.
Report an issue: GitHub.