TUS Resumable Uploads + Clerk JWT returning 403 RLS error
Need help: TUS resumable uploads with Clerk JWT getting 403 RLS error
Running into a persistent issue with resumable uploads using Clerk third-party auth. Would appreciate any guidance.
Setup:
- Next.js 15 + Clerk for authentication
- Supabase Storage with TUS protocol for resumable uploads
- Clerk configured as third-party provider (Dashboard → Auth → Third-Party)
- Using direct storage endpoint:
https://<project-id>.storage.supabase.co/storage/v1/upload/resumable
TUS request headers:
Problem:
- TUS POST returns 403 new row violates row-level security policy
- Storage auth test works (can list buckets with same Bearer token → returns 200)
- Small file uploads via service_role work fine
- Storage policies use requesting_user_id() which calls convert_to_uuid(auth.jwt()->>'sub')
RLS Policy (simplified):
Questions:
1. Does the Bearer token from Clerk.session.getToken() have the right format for Supabase Storage RLS?
2. Should I be using a different Clerk token method or template?
3. Is there a way to debug what requesting_user_id() returns during the Storage RLS evaluation?
What works:
- ✅ JWKS endpoint is accessible
- ✅ Storage auth test passes (listBuckets returns 200)
- ✅ JWT has sub, iss, role: "authenticated", exp
- ✅ User exists in project_members with proper role
What fails:
- ❌ TUS POST to /storage/v1/upload/resumable → 403 RLS1 Reply
My first suggestion would be in you
requesting_user_id function try and raise some logs using RAISE LOG 'lOG: %', auth.jwt(); or something similar and see the output that you are getting. I'm assuming that this is a database function you have defined somewhere and it is worth checking if it is in a format that you expect and that it'sv values point to something in the projects table
Also as a side note, just to isolate the issue down, if you simplify the RLS for that bucket to just authenticated users are things working for you?