nextauthjs/next-auth · error

[createSession] Failed to fetch created session

Error message

[createSession] Failed to fetch created session

What it means

The Firebase adapter's createSession adds a session document, then reads it back via ref.get(). If the resulting data is falsy it throws '[createSession] Failed to fetch created session'. The adapter insists on returning a fully materialized session, so a failed round-trip aborts sign-in.

Source

Thrown at packages/adapter-firebase/src/index.ts:178

      return account ?? null
    },

    async unlinkAccount({ provider, providerAccountId }) {
      await deleteDocs(
        C.accounts
          .where("provider", "==", provider)
          .where(mapper.toDb("providerAccountId"), "==", providerAccountId)
          .limit(1)
      )
    },

    async createSession(sessionInit) {
      const ref = await C.sessions.add(sessionInit)
      const session = await ref.get().then((doc) => doc.data())

      if (session) return session ?? null

      throw new Error("[createSession] Failed to fetch created session")
    },

    async getSessionAndUser(sessionToken) {
      const session = await getOneDoc(
        C.sessions.where(mapper.toDb("sessionToken"), "==", sessionToken)
      )
      if (!session) return null

      const user = await getDoc(C.users.doc(session.userId))
      if (!user) return null

      return { session, user }
    },

    async updateSession(partialSession) {
      const sessionId = await db.runTransaction(async (transaction) => {
        const sessionSnapshot = (
          await transaction.get(

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Check Firestore security rules allow reading documents the adapter just created in the sessions collection.
  2. Log sessionInit and verify the mapper produces non-empty fields before add().
  3. Confirm the adapter's Firestore instance points at the same project/database as the write.
  4. If a trigger cleans up session docs on create, remove or scope it.

Example fix

// before
const ref = await C.sessions.add(sessionInit)
const session = await ref.get().then((doc) => doc.data())
if (session) return session ?? null
throw new Error('[createSession] Failed to fetch created session')
// after
const ref = await C.sessions.add(sessionInit)
const snap = await ref.get()
if (!snap.exists) throw new Error('[createSession] Failed to fetch created session')
return { ...sessionInit, ...snap.data() }
Defensive patterns

Strategy: try-catch

Type guard

function hasSessionData(d: Record<string, unknown> | undefined): d is Record<string, unknown> {
  return !!d && Object.keys(d).length > 0
}

Try / catch

try {
  const session = await adapter.createSession(sessionInit)
  return session
} catch (e) {
  if ((e as Error).message.includes('Failed to fetch created session')) {
    console.error('Session create/read round-trip failed; check Firestore rules on sessions', e)
    throw e
  }
  throw e
}

Prevention

When it happens

Trigger: C.sessions.add(sessionInit) succeeds but the immediate get() returns empty data — security rules denying the read, sessionInit producing a doc with no fields, or a custom get/then helper failing to unwrap doc.data().

Common situations: Firestore rules that allow create but not read on the sessions collection (common with least-privilege configs); emulator/prod project mismatch; session payload mappers dropping all fields so data() comes back empty.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/4d7d7b8d330613e4. Report an issue: GitHub.