Skip to content
Back

OAuth login not working on deployed app (401 Bad credentials: No description user_oauth2_unauthorize

  • 0
  • Self Hosted
  • Auth
  • Web
.Seikatsu
2 Nov, 2025, 10:43

Hey there, I've been dealing with an issue where I cannot use OAuth on my deployed app - locally everything works fine.

I am using react-router in Framework Mode (with SSR). While developing locally, using OAuth (GitHub) without any issues. Now I've deployed my app, but I cannot get OAuth to work anymore (E-Mail login works fine tho!). I ha two projects in my self-hosted Appwrite Instance (development / production), both don't work. I've also tried Appwrite cloud, but I get the same OAuth issue there. Checked all settings multiple times, not no luck so far.

Looking at the requests, my app redirects to github which returns a 302 to the following url: https://appwrite.seikatsu.io/v1/account/sessions/oauth2/callback/github/6902414700388e783f69?code=XXXXX&state={"success":"https:\\/\\/evenup.seikatsu.io\\/auth\\/oauth\\/success","failure":"https:\\/\\/evenup.seikatsu.io\\/auth\\/oauth\\/failure","token":true}

Appwrite then returns a 301 with the following url: https://appwrite.seikatsu.io/v1/account/sessions/oauth2/github/redirect?code=XXXXX&state={"success":"https:\\/\\/evenup.seikatsu.io\\/auth\\/oauth\\/success","failure":"https:\\/\\/evenup.seikatsu.io\\/auth\\/oauth\\/failure","token":true}&project=6902414700388e783f69

There I get the 401 error.

TL;DR
OAuth login not working on deployed app, getting a 401 error. App redirects to GitHub, receives a 301 error. Works fine locally but not deployed. Issue occurs with Appwrite cloud and self-hosted instance. No solution provided.
.Seikatsu
2 Nov, 2025, 10:43

This is the action of my login page:

TypeScript
export const action = async ({ request }: Route.ActionArgs) => {
  const parseResult = await loginFormSchema.safeParseAsync(
    await request.formData(),
  )
  if (!parseResult.success) {
    return redirect('/')
  }

  const { account } = createAdminClient()

  if (parseResult.data.provider !== 'email') {
    const { BASE_URL } = getBackendEnv()
    const successUrl = new URL(BASE_URL)
    successUrl.pathname = '/auth/oauth/success'

    const failureUrl = new URL(BASE_URL)
    failureUrl.pathname = '/auth/oauth/failure'

    try {
      const redirectUrl = await account.createOAuth2Token({
        provider: parseResult.data.provider,
        success: successUrl.toString(),
        failure: failureUrl.toString(),
      })
      return redirect(redirectUrl)
    } catch (error) {
      console.error(error)
      throw error
    }
  }

  try {
    const session = await account.createEmailPasswordSession({
      email: parseResult.data.email,
      password: parseResult.data.password,
    })

    return redirect('/sign-in?success=true', {
      headers: await AppwriteAuthenticator.writeSession(
        request,
        session.secret,
        new Date(session.expire),
      ),
    })
  } catch (error) {
    if (error instanceof AppwriteException) {
      return {
        type: error.type,
        message: error.message,
      }
    } else {
      return {
        message: 'Something went wrong',
      }
    }
  }
}
Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more