Middleware works locally but when we deploy on Vercel the session cannot be parsed
Error: Invalid JWT form. A JWT consists of three parts separated by dots.
at (node_modules/@clerk/backend/dist/esm/index.js:64:4787)
at (node_modules/@clerk/backend/dist/esm/index.js:64:11143)
at (node_modules/@clerk/backend/dist/esm/index.js:64:13218)
at (node_modules/@clerk/backend/dist/esm/index.js:64:12937)
at (node_modules/@clerk/backend/dist/esm/index.js:64:13099)
at (node_modules/@clerk/backend/dist/esm/index.js:64:14093)
at (node_modules/@clerk/nextjs/dist/server/withClerkMiddleware.js:37:0)
at (node_modules/next/dist/esm/server/web/adapter.js:103:0) {
reason: 'token-invalid',
action: undefined
}
Provide a json with the dependencies used in your project (copy paste from yarn.lock / package-lock.json) or a github project / template that reproduces the issue.
*Include the @clerk/ packages and their versions!**
import { withClerkMiddleware, getAuth } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { routes } from './routes'
// Set the paths that don't require the user to be signed in
const publicPaths = [`/sign-in*`, `/sign-up*`]
const isPublic = (path: string) => {
return publicPaths.find((x) => path.match(new RegExp(`^${x}$`.replace('*$', '($|/)'))))
}
export default withClerkMiddleware((request: NextRequest) => {
if (isPublic(request.nextUrl.pathname)) {
return NextResponse.next()
}
// if the user is not signed in redirect them to the sign in page.
const { userId } = getAuth(request)
if (!userId) {
// redirect the users to /pages/sign-in/[[...index]].ts
const signInUrl = new URL(routes.signIn, request.url)
signInUrl.searchParams.set('redirect_url', request.url)
return NextResponse.redirect(signInUrl)
}
return NextResponse.next()
})
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - _next
* - static (static files)
* - favicon.ico (favicon file)
* - public folder
*/
'/(.*?trpc.*?|(?!static|.*\\..*|_next|favicon.ico|site.manifest).*)',
'/',
],
}
The root / is not public, and we check the user authentication in order to provide proper redirects
The result is that the user ends up on /sign-in page even when they are authenticated.
I've manually checked every JWT in localStorage and cookies and they are all with valid signatures - __session, clerk-db-jwt, __dev_session
The issue was resolved by re-applying the environment variables in Vercel, seems when the secret key contains whitespace or is wrong Invalid JWT form error is thrown.
Middleware works locally but when we deploy on Vercel the session cannot be parsed
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_cHVtcGVkLW1hZ2dvdC0yOS5jbGVyay5hY2NvdW50cy5kZXYk
Package + Version
@clerk/clerk-js
@clerk/clerk-react
@clerk/nextjs
^4.16.2
@clerk/remix
@clerk/types
@clerk/themes
^1.6.1
@clerk/localizations
@clerk/clerk-expo
@clerk/backend
@clerk/clerk-sdk-node
@clerk/shared
@clerk/fastify
@clerk/chrome-extension
gatsby-plugin-clerk
build/tooling/chore
Dependencies + versions
Provide a json with the dependencies used in your project (copy paste from yarn.lock / package-lock.json) or a github project / template that reproduces the issue.
*Include the @clerk/ packages and their versions!**
Example:
Browser/OS
Any
Description
We're using Clerk with tRPC in a similar way as it's defined in the starter https://github.com/clerkinc/t3-turbo-and-clerk
The
middleware.ts
is as follows:The root
/
is not public, and we check the user authentication in order to provide proper redirectsThe result is that the user ends up on
/sign-in
page even when they are authenticated.I've manually checked every JWT in localStorage and cookies and they are all with valid signatures -
__session
,clerk-db-jwt
,__dev_session
_clerk_js_version: 4.37.0