Clerk Auth - Breaking Changes & Error Prevention Guide
Package Versions: @clerk/nextjs@6.36.7, @clerk/backend@2.29.2, @clerk/clerk-react@5.59.2, @clerk/testing@1.13.26
Breaking Changes: Nov 2025 - API version 2025-11-10, Oct 2024 - Next.js v6 async auth()
Last Updated: 2026-01-09
What's New (Dec 2025 - Jan 2026)
1. API Keys Beta (Dec 11, 2025) - NEW ✨
User-scoped and organization-scoped API keys for your application. Zero-code UI component.
CODEBLOCK0
Backend Verification:
CODEBLOCK1
clerkMiddleware Token Types:
CODEBLOCK2
Pricing (Beta = Free):
- - Creation: $0.001/key
- Verification: $0.0001/verification
2. Next.js 16: proxy.ts Middleware Filename (Dec 2025)
⚠️ BREAKING: Next.js 16 changed middleware filename due to critical security vulnerability (CVE disclosed March 2025).
Background: The March 2025 vulnerability (affecting Next.js 11.1.4-15.2.2) allowed attackers to completely bypass middleware-based authorization by adding a single HTTP header: x-middleware-subrequest: true. This affected all auth libraries (NextAuth, Clerk, custom solutions).
Why the Rename: The middleware.ts → proxy.ts change isn't just cosmetic - it's Next.js signaling that middleware-first security patterns are dangerous. Future auth implementations should not rely solely on middleware for authorization.
CODEBLOCK3
Correct Setup for Next.js 16:
CODEBLOCK4
Minimum Version: @clerk/nextjs@6.35.0+ required for Next.js 16 (fixes Turbopack build errors and cache invalidation on sign-out).
3. Force Password Reset (Dec 19, 2025)
Administrators can mark passwords as compromised and force reset:
CODEBLOCK5
4. Organization Reports & Filters (Dec 15-17, 2025)
Dashboard now includes org creation metrics and filtering by name/slug/date.
API Version 2025-11-10 Breaking Changes
1. API Version 2025-11-10 (Nov 10, 2025) - BREAKING CHANGES ⚠️
Affects: Applications using Clerk Billing/Commerce APIs
Critical Changes:
- - Endpoint URLs:
/commerce/ → /billing/ (30+ endpoints)
CODEBLOCK6
- - Field Terminology:
payment_source → INLINECODE6
CODEBLOCK7
- - Removed Fields: Plans responses no longer include:
-
amount,
amount_formatted (use
fee.amount instead)
-
currency,
currency_symbol (use fee objects)
-
payer_type (use
for_payer_type)
-
annual_monthly_amount, INLINECODE15
- Invoices endpoint (use statements)
- Products endpoint
- - Null Handling: Explicit rules -
null means "doesn't exist", omitted means "not asserting existence"
Migration: Update SDK to v6.35.0+ which includes support for API version 2025-11-10.
Official Guide: https://clerk.com/docs/guides/development/upgrading/upgrade-guides/2025-11-10
2. Next.js v6 Async auth() (Oct 2024) - BREAKING CHANGE ⚠️
Affects: All Next.js Server Components using INLINECODE17
CODEBLOCK8
Also affects: auth.protect() is now async in middleware
CODEBLOCK9
Compatibility: Next.js 15, 16 supported. Static rendering by default.
3. PKCE Support for Custom OAuth (Nov 12, 2025)
Custom OIDC providers and social connections now support PKCE (Proof Key for Code Exchange) for enhanced security in native/mobile applications where client secrets cannot be safely stored.
Use case: Mobile apps, native apps, public clients that can't securely store secrets.
4. Client Trust: Credential Stuffing Defense (Nov 14, 2025)
Automatic secondary authentication when users sign in from unrecognized devices:
- - Activates for users with valid passwords but no 2FA
- No configuration required
- Included in all Clerk plans
How it works: Clerk automatically prompts for additional verification (email code, backup code) when detecting sign-in from new device.
5. Next.js 16 Support (Nov 2025)
@clerk/nextjs v6.35.2+ includes cache invalidation improvements for Next.js 16 during sign-out.
Critical Patterns & Error Prevention
Next.js v6: Async auth() Helper
Pattern:
CODEBLOCK10
Cloudflare Workers: authorizedParties (CSRF Prevention)
CRITICAL: Always set authorizedParties to prevent CSRF attacks
CODEBLOCK11
Why: Without authorizedParties, attackers can use valid tokens from other domains.
Source: https://clerk.com/docs/reference/backend/verify-token
clerkMiddleware() Configuration
Route Protection Patterns
CODEBLOCK12
All Middleware Options
| Option | Type | Description |
|---|
| INLINECODE21 | INLINECODE22 | Enable debug logging |
| INLINECODE23 |
string | JWKS public key for networkless verification |
|
clockSkewInMs |
number | Token time variance (default: 5000ms) |
|
organizationSyncOptions |
object | URL-based org activation |
|
signInUrl |
string | Custom sign-in URL |
|
signUpUrl |
string | Custom sign-up URL |
Organization Sync (URL-based Org Activation)
⚠️ Next.js Only: This feature currently only works with clerkMiddleware() in Next.js. It does NOT work with authenticateRequest() in other runtimes (Cloudflare Workers, Express, etc.) due to Sec-Fetch-Dest header checks.
Source: GitHub Issue #7178
CODEBLOCK13
Webhooks
Webhook Verification
CODEBLOCK14
Common Event Types
| Event | Trigger |
|---|
| INLINECODE36 | New user signs up |
| INLINECODE37 |
User profile changes |
|
user.deleted | User account deleted |
|
session.created | New sign-in |
|
session.ended | Sign-out |
|
organization.created | New org created |
|
organization.membership.created | User joins org |
⚠️ Important: Webhook routes must be PUBLIC (no auth). Add to middleware exclude list:
CODEBLOCK15
UI Components Quick Reference
| Component | Purpose |
|---|
| INLINECODE43 | Full sign-in flow |
| INLINECODE44 |
Full sign-up flow |
|
<SignInButton /> | Trigger sign-in modal |
|
<SignUpButton /> | Trigger sign-up modal |
|
<SignedIn> | Render only when authenticated |
|
<SignedOut> | Render only when unauthenticated |
|
<UserButton /> | User menu with sign-out |
|
<UserProfile /> | Full profile management |
|
<OrganizationSwitcher /> | Switch between orgs |
|
<OrganizationProfile /> | Org settings |
|
<CreateOrganization /> | Create new org |
|
<APIKeys /> | API key management (NEW) |
React Hooks
| Hook | Returns |
|---|
| INLINECODE55 | INLINECODE56 |
| INLINECODE57 |
{ user, isLoaded, isSignedIn } |
|
useClerk() | Clerk instance with methods |
|
useSession() | Current session object |
|
useOrganization() | Current org context |
|
useOrganizationList() | All user's orgs |
JWT Templates - Size Limits & Shortcodes
JWT Size Limitation: 1.2KB for Custom Claims ⚠️
Problem: Browser cookies limited to 4KB. Clerk's default claims consume ~2.8KB, leaving 1.2KB for custom claims.
⚠️ Development Note: When testing custom JWT claims in Vite dev mode, you may encounter "431 Request Header Fields Too Large" error. This is caused by Clerk's handshake token in the URL exceeding Vite's 8KB limit. See Issue #11 for solution.
Solution:
CODEBLOCK16
Best Practice: Store large data in database, include only identifiers/roles in JWT.
Available Shortcodes Reference
| Category | Shortcodes | Example |
|---|
| User ID & Name | INLINECODE63 , {{user.first_name}}, {{user.last_name}}, INLINECODE66 | INLINECODE67 |
| Contact |
{{user.primary_email_address}},
{{user.primary_phone_address}} |
"john@example.com" |
|
Profile |
{{user.image_url}},
{{user.username}},
{{user.created_at}} |
"https://..." |
|
Verification |
{{user.email_verified}},
{{user.phone_number_verified}} |
true |
|
Metadata |
{{user.public_metadata}},
{{user.public_metadata.FIELD}} |
{"role": "admin"} |
|
Organization |
org_id,
org_slug,
org_role (in sessionClaims) |
"org:admin" |
Advanced Features:
- - String Interpolation: INLINECODE85
- Conditional Fallbacks: INLINECODE86
- Nested Metadata: INLINECODE87
Official Docs: https://clerk.com/docs/guides/sessions/jwt-templates
Testing with Clerk
Test Credentials (Fixed OTP: 424242)
Test Emails (no emails sent, fixed OTP):
CODEBLOCK17
Test Phone Numbers (no SMS sent, fixed OTP):
CODEBLOCK18
Fixed OTP Code: 424242 (works for all test credentials)
Generate Session Tokens (60-second lifetime)
Script (scripts/generate-session-token.js):
CODEBLOCK19
Manual Flow:
- 1. Create user: INLINECODE90
- Create session: INLINECODE91
- Generate token: INLINECODE92
- Use in header: INLINECODE93
E2E Testing with Playwright
Install @clerk/testing for automatic Testing Token management:
CODEBLOCK20
Global Setup (global.setup.ts):
CODEBLOCK21
Test File (auth.spec.ts):
CODEBLOCK22
Official Docs: https://clerk.com/docs/guides/development/testing/overview
Known Issues Prevention
This skill prevents 15 documented issues:
Issue #1: Missing Clerk Secret Key
Error: "Missing Clerk Secret Key or API Key"
Source: https://stackoverflow.com/questions/77620604
Prevention: Always set in
.env.local or via INLINECODE98
Issue #2: API Key → Secret Key Migration
Error: "apiKey is deprecated, use secretKey"
Source: https://clerk.com/docs/upgrade-guides/core-2/backend
Prevention: Replace
apiKey with
secretKey in all calls
Issue #3: JWKS Cache Race Condition
Error: "No JWK available"
Source: https://github.com/clerk/javascript/blob/main/packages/backend/CHANGELOG.md
Prevention: Use @clerk/backend@2.17.2 or later (fixed)
Issue #4: Missing authorizedParties (CSRF)
Error: No error, but CSRF vulnerability
Source: https://clerk.com/docs/reference/backend/verify-token
Prevention: Always set INLINECODE101
Issue #5: Import Path Changes (Core 2)
Error: "Cannot find module"
Source: https://clerk.com/docs/upgrade-guides/core-2/backend
Prevention: Update import paths for Core 2
Issue #6: JWT Size Limit Exceeded
Error: Token exceeds size limit
Source: https://clerk.com/docs/backend-requests/making/custom-session-token
Prevention: Keep custom claims under 1.2KB
Issue #7: Deprecated API Version v1
Error: "API version v1 is deprecated"
Source: https://clerk.com/docs/upgrade-guides/core-2/backend
Prevention: Use latest SDK versions (API v2025-11-10)
Issue #8: ClerkProvider JSX Component Error
Error: "cannot be used as a JSX component"
Source: https://stackoverflow.com/questions/79265537
Prevention: Ensure React 19 compatibility with @clerk/clerk-react@5.59.2+
Issue #9: Async auth() Helper Confusion
Error: "auth() is not a function"
Source: https://clerk.com/changelog/2024-10-22-clerk-nextjs-v6
Prevention: Always await: INLINECODE102
Issue #10: Environment Variable Misconfiguration
Error: "Missing Publishable Key" or secret leaked
Prevention: Use correct prefixes (
NEXT_PUBLIC_,
VITE_), never commit secrets
Issue #11: 431 Request Header Fields Too Large (Vite Dev Mode)
Error: "431 Request Header Fields Too Large" when signing in
Source: Common in Vite dev mode when testing custom JWT claims
Cause: Clerk's
__clerk_handshake token in URL exceeds Vite's 8KB header limit
Prevention:
Add to package.json:
CODEBLOCK23
Temporary Workaround: Clear browser cache, sign out, sign back in
Why: Clerk dev tokens are larger than production; custom JWT claims increase handshake token size
Note: This is different from Issue #6 (session token size). Issue #6 is about cookies (1.2KB), this is about URL parameters in dev mode (8KB → 32KB).
Issue #12: User Type Mismatch (useUser vs currentUser)
Error: TypeScript errors when sharing user utilities across client/server
Source:
GitHub Issue #2176
Why It Happens:
useUser() returns
UserResource (client-side) with different properties than
currentUser() returns
User (server-side). Client has
fullName,
primaryEmailAddress object; server has
primaryEmailAddressId and
privateMetadata instead.
Prevention: Use shared properties only, or create separate utility functions for client vs server contexts.
CODEBLOCK24
Issue #13: Multiple acceptsToken Types Causes token-type-mismatch
Error: "token-type-mismatch" when using
authenticateRequest() with multiple token types
Source:
GitHub Issue #7520
Why It Happens: When using
authenticateRequest() with multiple
acceptsToken values (e.g.,
['session_token', 'api_key']), Clerk incorrectly throws token-type-mismatch error.
Prevention: Upgrade to @clerk/backend@2.29.2+ (fix available in snapshot, releasing soon).
CODEBLOCK25
Issue #14: deriveUrlFromHeaders Server Crash on Malformed URLs
Error: Server crashes with URL parsing error
Source:
GitHub Issue #7275
Why It Happens: Internal
deriveUrlFromHeaders() function performs unsafe URL parsing and crashes the entire server when receiving malformed URLs in headers (e.g.,
x-forwarded-host: 'example.com[invalid]'). This is a denial-of-service vulnerability.
Prevention: Upgrade to @clerk/backend@2.29.0+ (fixed).
Issue #15: treatPendingAsSignedOut Option for Pending Sessions
Error: None - optional parameter for edge case handling
Source:
Changelog @clerk/nextjs@6.32.0
Why It Exists: Sessions can have a
pending status during certain flows (e.g., credential stuffing defense secondary auth). By default, pending sessions are treated as signed-out (user is null).
Usage: Set
treatPendingAsSignedOut: false to treat pending as signed-in (available in @clerk/nextjs@6.32.0+).
CODEBLOCK26
Production Considerations
Service Availability & Reliability
Context: Clerk experienced 3 major service disruptions in May-June 2025 attributed to Google Cloud Platform (GCP) outages. The June 26, 2025 outage lasted 45 minutes (6:16-7:01 UTC) and affected all Clerk customers.
Source: Clerk Postmortem: June 26, 2025
Mitigation Strategies:
- - Monitor Clerk Status for real-time updates
- Implement graceful degradation when Clerk API is unavailable
- Cache auth tokens locally where possible
- For existing sessions, use
jwtKey option for networkless verification:
CODEBLOCK27
Note: During total outage, no new sessions can be created (auth requires Clerk API). However, existing sessions can continue working if you verify JWTs locally with jwtKey. Clerk committed to exploring multi-cloud redundancy to reduce single-vendor dependency risk.
Official Documentation
- - Clerk Docs: https://clerk.com/docs
- Next.js Guide: https://clerk.com/docs/references/nextjs/overview
- React Guide: https://clerk.com/docs/references/react/overview
- Backend SDK: https://clerk.com/docs/reference/backend/overview
- JWT Templates: https://clerk.com/docs/guides/sessions/jwt-templates
- API Version 2025-11-10 Upgrade: https://clerk.com/docs/guides/development/upgrading/upgrade-guides/2025-11-10
- Testing Guide: https://clerk.com/docs/guides/development/testing/overview
- Context7 Library ID: INLINECODE125
Package Versions
Latest (Nov 22, 2025):
{
"dependencies": {
"@clerk/nextjs": "^6.36.7",
"@clerk/clerk-react": "^5.59.2",
"@clerk/backend": "^2.29.2",
"@clerk/testing": "^1.13.26"
}
}
Token Efficiency:
- - Without skill: ~6,500 tokens (setup tutorials, JWT templates, testing setup, webhooks, production considerations)
- With skill: ~3,200 tokens (breaking changes + critical patterns + error prevention + production guidance)
- Savings: ~51% (~3,300 tokens)
Errors prevented: 15 documented issues with exact solutions
Key value: API Keys beta, Next.js 16 proxy.ts (with March 2025 CVE context), clerkMiddleware() options, webhooks, component reference, API 2025-11-10 breaking changes, JWT size limits, user type mismatches, production considerations (GCP outages, jwtKey offline verification)
Last verified: 2026-01-20 |
Skill version: 3.1.0 |
Changes: Added 4 new Known Issues (#12-15: user type mismatch, acceptsToken type mismatch, deriveUrlFromHeaders crash, treatPendingAsSignedOut option), expanded proxy.ts section with March 2025 CVE security context, added Production Considerations section (GCP outages + mitigation), added organizationSyncOptions Next.js-only limitation note, updated minimum version requirements for Next.js 16 (6.35.0+).
Clerk Auth - 重大变更与错误预防指南
包版本: @clerk/nextjs@6.36.7, @clerk/backend@2.29.2, @clerk/clerk-react@5.59.2, @clerk/testing@1.13.26
重大变更: 2025年11月 - API版本2025-11-10, 2024年10月 - Next.js v6异步auth()
最后更新: 2026-01-09
新功能 (2025年12月 - 2026年1月)
1. API密钥测试版 (2025年12月11日) - 全新 ✨
适用于应用程序的用户级和组织级API密钥。零代码UI组件。
typescript
// 1. 添加自助API密钥管理组件
import { APIKeys } from @clerk/nextjs
export default function SettingsPage() {
return (
API Keys
{/
用户API密钥的完整CRUD界面 /}
)
}
后端验证:
typescript
import { verifyToken } from @clerk/backend
// API密钥与会话令牌的验证方式相同
const { data, error } = await verifyToken(apiKey, {
secretKey: process.env.CLERKSECRETKEY,
authorizedParties: [https://yourdomain.com],
})
// 检查令牌类型
if (data?.tokenType === api_key) {
// 处理API密钥认证
}
clerkMiddleware令牌类型:
typescript
// v6.36.0+: 中间件可以区分令牌类型
clerkMiddleware((auth, req) => {
const { userId, tokenType } = auth()
if (tokenType === api_key) {
// API密钥认证 - 程序化访问
} else if (tokenType === session_token) {
// 常规会话 - Web界面访问
}
})
定价 (测试版 = 免费):
- - 创建: $0.001/密钥
- 验证: $0.0001/验证
2. Next.js 16: proxy.ts中间件文件名 (2025年12月)
⚠️ 重大变更: Next.js 16因关键安全漏洞(2025年3月披露的CVE)更改了中间件文件名。
背景: 2025年3月的漏洞(影响Next.js 11.1.4-15.2.2)允许攻击者通过添加单个HTTP头x-middleware-subrequest: true完全绕过基于中间件的授权。这影响了所有认证库(NextAuth、Clerk、自定义解决方案)。
重命名原因: middleware.ts → proxy.ts的更改不仅仅是表面上的 - 它标志着Next.js表明中间件优先的安全模式是危险的。未来的认证实现不应仅依赖中间件进行授权。
Next.js 15及更早版本: middleware.ts
Next.js 16+: proxy.ts
Next.js 16的正确设置:
typescript
// src/proxy.ts (不是 middleware.ts!)
import { clerkMiddleware } from @clerk/nextjs/server
export default clerkMiddleware()
export const config = {
matcher: [
/((?!_next|[^?]\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).),
/(api|trpc)(.*),
],
}
最低版本: Next.js 16需要@clerk/nextjs@6.35.0+(修复Turbopack构建错误和退出登录时的缓存失效)。
3. 强制密码重置 (2025年12月19日)
管理员可以将密码标记为已泄露并强制重置:
typescript
import { clerkClient } from @clerk/backend
// 强制用户重置密码
await clerkClient.users.updateUser(userId, {
passwordDigest: compromised, // 下次登录时触发重置
})
4. 组织报告与筛选 (2025年12月15-17日)
仪表板现在包括组织创建指标以及按名称/别名/日期筛选的功能。
API版本2025-11-10重大变更
1. API版本2025-11-10 (2025年11月10日) - 重大变更 ⚠️
影响: 使用Clerk计费/商务API的应用程序
关键变更:
- - 端点URL: /commerce/ → /billing/ (30+个端点)
GET /v1/commerce/plans → GET /v1/billing/plans
GET /v1/commerce/statements → GET /v1/billing/statements
POST /v1/me/commerce/checkouts → POST /v1/me/billing/checkouts
- - 字段术语: paymentsource → paymentmethod
typescript
// 旧版 (已弃用)
{ payment
sourceid: ..., payment_source: {...} }
// 新版 (必需)
{ paymentmethodid: ..., payment_method: {...} }
- amount, amount_formatted (改用fee.amount)
- currency, currency_symbol (使用费用对象)
- payer
type (使用forpayer_type)
- annual
monthlyamount, annual_amount
- 发票端点 (使用账单)
- 产品端点
- - 空值处理: 明确规则 - null表示不存在,省略表示不断言存在
迁移: 更新SDK至v6.35.0+,该版本包含对API版本2025-11-10的支持。
官方指南: https://clerk.com/docs/guides/development/upgrading/upgrade-guides/2025-11-10
2. Next.js v6异步auth() (2024年10月) - 重大变更 ⚠️
影响: 所有使用auth()的Next.js服务器组件
typescript
// ❌ 旧版 (v5 - 同步)
const { userId } = auth()
// ✅ 新版 (v6 - 异步)
const { userId } = await auth()
同样影响: auth.protect()在中间件中现在是异步的
typescript
// ❌ 旧版 (v5)
auth.protect()
// ✅ 新版 (v6)
await auth.protect()
兼容性: 支持Next.js 15、16。默认静态渲染。
3. 自定义OAuth的PKCE支持 (2025年11月12日)
自定义OIDC提供商和社交连接现在支持PKCE(代码交换证明密钥),用于无法安全存储客户端密钥的原生/移动应用程序,增强安全性。
使用场景: 移动应用、原生应用、无法安全存储密钥的公共客户端。
4. 客户端信任:凭证填充防御 (2025年11月14日)
当用户从未知设备登录时自动进行二次认证:
- - 对拥有有效密码但未启用2FA的用户激活
- 无需配置
- 包含在所有Clerk计划中
工作原理: 当检测到从新设备登录时,Clerk自动提示额外验证(邮箱验证码、备用验证码)。
5. Next.js 16支持 (2025年11月)
@clerk/nextjs v6.35.2+ 包含Next.js 16退出登录时的缓存失效改进。
关键模式与错误预防
Next.js v6: 异步auth()辅助函数
模式:
typescript
import { auth } from @clerk/nextjs/server
export default async function Page() {
const { userId } = await auth() // ← 必须await
if (!userId) {
return
未授权
}
return
用户ID: {userId}
}
Cloudflare Workers: authorizedParties (CSRF预防)
关键: 始终设置authorizedParties以防止CSRF攻击
typescript
import { verifyToken } from @clerk/backend
const { data, error } = await verifyToken(token, {
secretKey: c.env.CLERKSECRETKEY,
// 必需: 防止CSRF攻击
authorizedParties: [https://yourdomain.com],
})
原因: 没有authorizedParties,攻击者可以使用来自其他域的有效令牌。
来源: https://clerk.com/docs/reference/backend/verify-token
clerkMiddleware()配置
路由保护模式
typescript
import { clerkMiddleware, createRouteMatcher } from @clerk/nextjs/server
// 定义受保护路由
const isProtectedRoute = createRouteMat