#isAuthenticated false
33 messages · Page 1 of 1 (latest)
Hi @lime shard. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
I'm sorry, but there is no information in the provided knowledge sources regarding a provider called auClient.useSession. However, based on similar issues with other authentication providers (like WorkOS, Better Auth, or Clerk), if isAuthenticated from useConvexAuth() remains false despite a successful login and a valid JWT, here are the potential causes and steps to resolve it:
1. Missing Backend Configuration Sync
The most common cause is that the backend configuration has not been synchronized. Your auth.config.ts file must be synced to the Convex cloud.
- Solution: Run
npx convex devornpx convex deployafter any change toauth.config.tsto ensure the authentication provider settings are applied to your backend [Debugging Authentication; Debugging Authentication].
2. JWT Audience (aud) or Issuer (iss) Mismatches
Even if you believe they are correct, Convex requires an exact match between the JWT payload and your auth.config.ts.
- Audience: Ensure the
applicationIDin yourauth.config.tsmatches theaudclaim in your JWT exactly. Some providers like WorkOS may require you to manually enable theaudclaim in their dashboard to include your Client ID [Debugging Authentication]. - Issuer: The
issuerinauth.config.tsmust match theissclaim in the JWT.
3. Missing ConvexProviderWithAuth
If the React client isn't configured to fetch and pass the JWT to Convex, isAuthenticated will remain false.
- Solution: Ensure you are using
ConvexProviderWithAuth(or a provider-specific one likeConvexProviderWithClerk) and that theuseAuthprop is correctly passing the token. TheuseAuthhook must return afetchAccessTokenfunction that Convex calls to get the JWT [Provide the JWT to the Convex React client; Functions].
4. Race Conditions and WebSockets
After receiving a token, the client must send an Authenticate message over the WebSocket to the Convex deployment.
- Debugging: Open your browser's Network tab, filter for
WS(WebSockets), and look for thesyncconnection. Check the "Messages" tab for a message withtype: "Authenticate". If you don't see this message or if it contains an empty value, the token is not being passed to the Convex client [Check whether authentication works on the frontend]. - Timing: There can be a slight delay between your auth provider confirming a session and the Convex WebSocket completing authentication. Ensure you are respecting the
isLoadingstate fromuseConvexAuth()[Redirecting to a protected route after a successful sign-in not working properly].
5. Domain/Environment Variables
Check if your auth.config.ts relies on environment variables (like CONVEX_SITE_URL) that might be undefined in your local or production environment. If the domain is undefined, JWT validation will fail [getAuthUserId() Returns Null Despite Successful OAuth Sign-In].
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@lime shard Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@elfin axle I m using ConvexBetterAuthProvider
Let me check the knowledge base for you again. One moment! :books:
If you are using ConvexBetterAuthProvider and isAuthenticated remains false despite a successful session in Better Auth, it usually indicates that the Convex client has not yet successfully validated the session token with the Convex backend.
Based on the knowledge sources, here are the troubleshooting steps specifically for the Better Auth + Convex integration:
1. Verification of auth.config.ts
Convex must be configured to trust the tokens issued by Better Auth. Ensure your convex/auth.config.ts matches your Better Auth deployment.
- Issuer and Audience: The
issuerandapplicationIDin your config must match theissandaudclaims in the JWT provided by Better Auth. - JWKS Endpoint: If you are not using a standard provider, you may need to expose the JWKS endpoint via a Convex HTTP action so the backend can verify the signatures [Better Auth with MongoDB and Convex for client data].
2. Client-Side Plugin Initialization
Ensure your Better Auth client is initialized with the convexClient() plugin. This plugin is responsible for making the session token available to the ConvexBetterAuthProvider. Without this, useConvexAuth will not receive the token to pass to the Convex backend [Better Auth + Convex: isLoading never resolves and authenticated queries never run].
3. Check for expectAuth: true
If you configured your ConvexReactClient with { expectAuth: true }, all queries will be paused until authentication is complete. If there is a configuration mismatch, the client may get stuck in an isLoading state indefinitely.
- Try: Temporarily remove
expectAuth: trueto see if queries start running (even if they returnnullfor identity), which helps isolate whether the issue is the WebSocket authentication flow [Better Auth + Convex: isLoading never resolves and authenticated queries never run].
4. Better Auth Session vs. Convex Auth
It is important to note that Better Auth will reflect an authenticated user (via authClient.useSession()) before Convex does. The Convex client must take that session, exchange/validate the token with the Convex backend, and only then will useConvexAuth().isAuthenticated become true [Authorization].
Always use useConvexAuth() or the <Authenticated> helper component to gate your logic, as calling Convex functions before the Convex-specific validation completes can lead to errors [Authorization].
5. Debugging the Token
If the issue persists, verify the JWT:
- Check the browser's Network tab for the
syncWebSocket connection. - Look for an
Authenticatemessage. - Copy the token and paste it into jwt.io to ensure the
issandaudfields match exactly what you have inauth.config.ts[Check whether authentication works on the frontend].
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@lime shard Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@elfin axle i get this after login but isAuthenticated still false
isAuthenticated
1/10/2026, 2:54:25 PM [CONVEX H(GET /api/auth/get-session)] [LOG] 'response headers' Headers { 'set-cookie': '__Secure-better-auth.convex_jwt=eyJhb....
1/10/2026, 2:54:25 PM [CONVEX H(GET /api/auth/get-session)] [LOG] '2026-01-10T13:54:25.324Z INFO [Better Auth]: [Convex Adapter]' '#3 \x1B[40m\x1B[33m[3/3]\x1B[0m' '\x1B[1mfindMany\x1B[0m \x1B[2m(Parsed Result)\x1B[0m:' {
model: 'jwks',
data: [
{
publicKey: '{"kty":"RSA","n":"xsdaE55e
1/10/2026, 2:54:25 PM [CONVEX H(GET /api/auth/get-session)] [LOG] '2026-01-10T13:54:25.324Z INFO [Better Auth]: [Convex Adapter]' '#3 \x1B[40m\x1B[33m[2/3]\x1B[0m' '\x1B[1mfindMany\x1B[0m \x1B[2m(DB Result)\x1B[0m:' {
model: 'jwks',
data: [
{
_creationTime: 1767814581243.6265,
_id: 'kd7fcmf4827zk18ph3ntr8x1ed7yr20n',
createdAt: 1767814581242,
privateKey: '"bea4dc192ae9d0
1/10/2026, 2:54:25 PM [CONVEX H(GET /api/auth/get-session)] [LOG] '2026-01-10T13:54:25.320Z INFO [Better Auth]: [Convex Adapter]' '#2 \x1B[40m\x1B[33m[3/3]\x1B[0m' '\x1B[1mfindOne\x1B[0m \x1B[2m(Parsed Result)\x1B[0m:' {
model: 'session',
data: {
expiresAt: 1768635097746,
token: 'IX5wto3NSq38Mlu8GXq5vu2kGZhant7Z',
createdAt: 1768030297746,
updatedAt: 1768030297746,
ipAddress: 'XXXX',
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36',
userId: 'k571qg3n8rhktcgsjw761knh2d7yxz6n',
impersonatedBy: undefined,
id: 'jx711psv34tar1fw6x1zn1wqwx7yzf5c',
user: {
name:
Let me check the knowledge base for you again. One moment! :books:
The logs show that Better Auth is successfully creating a session and setting the __Secure-better-auth.convex_jwt cookie. However, isAuthenticated remaining false on the client indicates that the Convex React client has not yet received or successfully validated that token with the Convex backend.
Based on the knowledge sources, here are the likely reasons for this behavior:
1. Verification of auth.config.ts
The most common reason isAuthenticated stays false even when a token exists is that the Convex backend is rejecting the JWT because the configuration doesn't match.
- Issuer Match: Better Auth typically uses your
CONVEX_SITE_URLas the issuer. Ensure yourconvex/auth.config.tshas the exact same URL (including<https://> and no trailing slash) [No JWT Token when using better-auth with Next.js SSR on login]. - Application ID: Ensure the
applicationIDinauth.config.tsis set to"convex", which is the default audience used by the Better Auth Convex plugin.
2. JWT Validation via JWKS
Your logs show Better Auth fetching jwks from the database. For Convex to validate the JWT, it needs to access these public keys.
- If you are not using the
experimental.jwksfeature, Convex tries to fetch the keys from your Better Auth deployment at runtime. - Experimental Optimization: To speed this up and avoid validation failures, you can provide the JWKS statically to the auth config. You can run
npx convex run auth:getLatestJwks | npx convex env set JWKSand update yourauth.config.tsto useprocess.env.JWKS[Experimental].
3. Client-Side Race Condition
In frameworks like Next.js, the better-auth.convex_jwt cookie is set during the login request, but the Convex WebSocket might already be connected and waiting.
- The Convex client needs to "see" that token change. If you are using
ConvexBetterAuthProvider, it relies on the Better Auth client's state. - There is a known issue where the
convex_jwtmight not be immediately available to the client-side session without a refresh if using certain plugins or older versions of the adapter [No JWT Token when using better-auth with Next.js SSR on login]. Ensure you are on the latest version of@convex-dev/better-auth.
4. Debugging the Validation Failure
To see exactly why the backend is keeping isAuthenticated false, you can enable verbose logging:
- Backend: Set the environment variable
AUTH_LOG_LEVELtoDEBUGin your Convex dashboard. This will log exactly why a JWT validation failed (e.g., "invalid issuer" or "could not fetch JWKS") [Debugging]. - Client: Initialize your
ConvexReactClientwithverbose: trueto see if the "Authenticate" message is being sent over the WebSocket [Debugging].
const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!, {
verbose: true,
});
If the Authenticate message is sent but isAuthenticated stays false, the issue is almost certainly a mismatch in auth.config.ts regarding the domain (issuer) or applicationID (audience) [Step 3: Check that backend configuration matches frontend configuration].
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@lime shard Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@elfin axle better auth while authenticated, useConvexAuth isLoading remain true
Let me check the knowledge base for you again. One moment! :books:
If useConvexAuth().isLoading remains stuck at true while using Better Auth, it typically means the Convex client is waiting for authentication to resolve but has not received a definitive success or failure from the backend.
Based on the knowledge sources, here are the primary reasons and solutions for this state:
1. expectAuth: true is enabled
If you initialized your ConvexReactClient with the expectAuth: true option, Convex will pause all query execution and remain in a loading state until the user is successfully authenticated. If there is any misconfiguration in your auth setup, the client will stay in isLoading: true indefinitely because it is waiting for a valid JWT that never clears validation [Better Auth + Convex: isLoading never resolves and authenticated queries never run].
- Solution: Try setting
expectAuth: false(or removing it) to see if the state transitions toisAuthenticated: false, which confirms the backend is rejecting the token rather than the client simply waiting [Better Auth + Convex: isLoading never resolves and authenticated queries never run].
2. JWT Validation Latency (JWKS Fetching)
By default, the Convex backend must perform two blocking HTTP requests to validate a Better Auth token: one for OIDC discovery and one to fetch the JWKS (JSON Web Key Set). This can cause the authentication process to be slow or hang if these external requests fail.
- Solution: Use Static JWKS to speed up validation. You can fetch your JWKS and store it as a Convex environment variable. This allows the backend to validate tokens locally without external network calls [Experimental].
3. Missing Client-Side Plugin
The Better Auth client must be configured with the convexClient() plugin to properly communicate the session state to the ConvexBetterAuthProvider.
- Check: Ensure your
authClientinitialization includes theconvexplugin:Without this plugin, the provider may never receive the token required to transition from the loading state [Better Auth + Convex: isLoading never resolves and authenticated queries never run].import { convexClient } from "@convex-dev/better-auth/client"; export const authClient = createAuthClient({ plugins: [ convexClient() ] });
4. Debugging the "Hang"
To identify exactly why the loading state isn't resolving, you can:
- Check WebSocket Traffic: Open the browser Network tab, filter for
WS, and look at thesyncconnection. Look for anAuthenticatemessage. If the message is sent but never receives a confirmation, the backend is struggling to validate it [Check whether authentication works on the frontend]. - Enable Verbose Logging: Set
AUTH_LOG_LEVELtoDEBUGin your Convex dashboard. This will reveal if the backend is silently failing during token validation, which keeps the client in a waiting state [Debugging].
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@lime shard Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@elfin axle looks at this https://discord.com/channels/1019350475847499849/1443243345609621594
Let me check the knowledge base for you again. One moment! :books:
I'm sorry, but I do not have access to the specific content of the Discord link you provided (1443243345609621594), as it is not included in the knowledge sources provided to me.
However, based on the relevant knowledge sources regarding Better Auth and Convex authentication staying in a loading state, the most common solution for this specific "infinite loading" behavior is:
- Check for
expectAuth: true: If you haveexpectAuth: truein yourConvexReactClientconfiguration, it will pause all queries and remain in anisLoadingstate until authentication is fully resolved. If there is a configuration mismatch, it may never resolve. Staff recommend turning this off to troubleshoot if the state then transitions toisAuthenticated: false[Better Auth + Convex: isLoading never resolves and authenticated queries never run; INFINITE loading state]. - Verify the
convexClient()plugin: Ensure your Better Auth client is initialized with theconvexClient()plugin, which is required for theConvexBetterAuthProviderto receive the token [Better Auth + Convex: isLoading never resolves and authenticated queries never run]. - Backend Config Sync: Ensure you have run
npx convex devafter setting up yourauth.config.ts. If the backend doesn't have the provider info, the validation request will never complete successfully [Debugging Authentication].
If you can share the specific error or code snippet from that thread, I may be able to provide more targeted help based on the documents I have.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@lime shard Kapa.ai is still learning and improving, please let me know how I did by reacting below.
i remove expectAuth , convexClient os correct and auth.config.ts is deployed
https://github.com/get-convex/convex-js/issues/108
@elfin axle i remove expectAuth , convexClient os correct and auth.config.ts is deployed
https://github.com/get-convex/convex-js/issues/108
Let me check the knowledge base for you again. One moment! :books:
I'm sorry, but the provided knowledge sources do not contain information regarding the GitHub issue get-convex/convex-js/issues/108 or the specific details of that discussion.
However, if you have removed expectAuth, confirmed your convexClient() plugin is correct, and deployed your auth.config.ts, but isLoading still remains true or isAuthenticated remains false, the knowledge sources point to a few remaining potential causes:
- Cookie Accessibility: In Next.js and other frameworks, the
convex_jwtis often stored in a cookie. If the cookie is not being sent with the Convex WebSocket connection (for example, due to CORS issues or the cookie being marked as__Host-but the client running on a different subdomain), the Convex client will never receive the token to start the authentication process [Debugging]. - Static JWKS Mismatch: If you are using the static JWKS optimization, ensure that the keys in your
JWKSenvironment variable exactly match the keys being used by your Better Auth instance to sign the tokens. If they do not match, validation will fail silently on the backend, potentially leaving the client waiting [Experimental]. - Issuer URL Precision: The
domaininauth.config.tsmust be a character-for-character match with theissclaim in your JWT. This includes the protocol (<https://>) and the absence of a trailing slash. If yourBETTER_AUTH_URLdiffers even slightly from what is inauth.config.ts, authentication will fail [No JWT Token when using better-auth with Next.js SSR on login].