Could not validate token during sync with better-auth
Hi! I'm using better-auth as my external auth service (not using convex-better-auth component), powered by TanStack Start, and I'm using it to authorize requests to Convex functions. I've set it all up following the Custom JWT Provider, but when my application tries to connect to Convex and connects the
sync
websocket, I'm getting Could not validate token
.
I've followed the Debugging Authentication doc multiple times, and I can't find the root cause. Yesterday, I could see the decoded token in the function, while getting this error. Today, without having changed anything related to auth, I'm not even getting the decoded token.
I don't see any valid reason for this error to come up. I'll post some more details in thread. Any idea?Debugging Authentication | Convex Developer Hub
You have followed one of our authentication guides but something is not working.
5 Replies
Thanks for posting in <#1088161997662724167>.
Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets.
- Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.)
- Use search.convex.dev to search Docs, Stack, and Discord all at once.
- Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI.
- Avoid tagging staff unless specifically instructed.
Thank you!
Here are some details from my investigation :
- Initially, I ran into some issue to expose my local JWKS endpoint, since I'm using better-auth , but I managed to work-around it by exposing it via a CloudFlare worker.
- By default, better-auth JWT tokens don't have the
"typ": "JWT"
header, but even after modifying the lib to include that, the error is still here.
- I figured the error was returned from this specific line from the back-end : https://github.com/get-convex/convex-backend/blob/a6c7aec0130dc7f6f49c9fcf898d7c40030ef8ba/crates/authentication/src/lib.rs#L317. Thus, I've roughly copied the code to try to validate it locally, and see if I could get a more relevant error (suspecting it could be related to the time-based claims). But the JWT is correctly validated locally using the same code:GitHub
convex-backend/crates/authentication/src/lib.rs at a6c7aec0130dc7f6...
The open-source reactive database for app developers - get-convex/convex-backend
Regarding my auth config, it looks like this:
I wouldn't mind sharing the JWKS and a JWT for an anonymous user if you'd like
I've thought about it more, and the only likely cause of this would be if my computer is more than one second ahead of convex backend, which would invalidate the iat claim, as the token would seem like it has been generated in the future
But in that case, I can't really see any solution to it (+ on windows 11 there's a button to sync time, and it didn't change anything)
Perhaps I have to deploy my auth service and use it locally, idk
Some updates on this:
- Yesterday night, for some unknown reason, it worked (meaning that I can see the user identity in the Convex function, and I didn't see the error in the
sync
websocket. I didn't change anything after that.
- This morning, I tried again and the error is here again, and the Convex function doesn't have the user identity.
I really don't understand why this is so inconsistentLooking at where that error is throwing in the backend, I'm pretty sure only expiry is being evaluated. Seems time based. Wondering if there are time differences between the systems you're using that's causing issues?
Hi! I checked the
biscuit
package that is used, and yeah, expiry is checked, along with claims like iat, iss, and aud
That's what I thought too, but I can't find a way to validate that theory; I live in France, so UTC+2, but the timestamp generated should be on UTC (and I've checked that when decoding the generated JWT tokens). And syncing my Windows time doesn't change anything (though, I'm using WSL, but I guess it should be the same time)
If you'd like, here's a JWT for a local anonymous user I have:
Okay, so I think the issue was not about the Windows time being out of sync, but I think we WSL time. I'm not super sure, there's not a clean way to know the time shift, but it seemed like my WSL was one second late for some unknown reason. That could explain the inconsistency of getting this error or not. Though, if it was one second late, I don't really understand why the token claims would be invalidated. It's not like it was 1 second ahead and the iat claim was a future date. Just in case: https://tomssl.com/fixing-clock-drift-in-wsl2-using-windows-terminal/
I'll keep this updated if I run into this issue again. Thanks!
I'll mark this as resolved as I mostly don't see this error anymore, or if I do, syncing the time on WSL works every time 👍