Local Storage TUS rejects signed upload token generated by the same stack with "Invalid Compact JWS"
Maintainers usually reply within 1 day
Assessment
This issue has not been assessed yet.
Description
Summary
createSignedUploadUrl generates a signed upload token in a clean local Supabase stack. The token is structurally a valid three-segment compact JWS using HS256, but the initial TUS request is rejected with Invalid Compact JWS.
The same result occurs through the local API gateway and directly against the Storage container. The reproducer contains no application code.
The attached results were captured during an earlier isolated diagnostic run. This package-preparation pass did not re-run the matrix.
Environment
- Windows x64
- Docker 29.6.2
- Bun 1.3.14
- Node 24.18.0
- Supabase CLI 2.109.1
- storage-api v1.62.5
- image digest
1dbe962d9862ef12e20357f9d7ba5431989c1daf4a556d6cb20ee4efd1c57320
- Supabase CLI 2.109.0
- storage-api v1.61.7
- image digest
7dae5013474c1b5f816d138605e33434d83b87df1716032cf588a15561dcd937
Reproduction
- Start a clean isolated local stack using one of the exact CLI versions.
- Create a private bucket through the official Storage API.
- Call
createSignedUploadUrlfor a random temporary object. - Verify only that the token is a decodable three-segment compact JWS with
alg = HS256. - Send the initial resumable upload request with standard TUS metadata,
x-signature, andx-upsert: false. - Observe HTTP 400 and
Invalid Compact JWS. - Send the same request and token directly to the Storage container through stdin.
- Observe the same result.
Relevant files:
src/reproduce.tssrc/run-cli-matrix.tssrc/sanitize.tssrc/verify-no-secrets.ts
Minimal reproduction command
bun install --frozen-lockfile
bun run matrix
bun run verify
An optional trusted CA file can be supplied with --cafile <path-to-trusted-ca.pem> when local HTTPS inspection is enabled.
Expected behavior
The initial TUS request should accept the signed upload token generated by the same local Storage stack and create a resumable upload session with a session location.
Actual behavior
During the earlier isolated diagnostic run:
- Gateway: HTTP 400,
Invalid Compact JWS/invalid_compact_jws - Direct Storage container: HTTP 400,
Invalid Compact JWS/invalid_compact_jws - No TUS session was created
Control observations
- The token was a compact JWS.
- It contained three segments.
- The protected header was decodable.
- The reported algorithm was HS256.
- The same local stack generated and rejected the token.
- Direct-container control rules out the gateway as the exclusive cause.
- No token transformation, manually generated signature, public bucket, upsert, policy change, or JWT-validation workaround was used.
Version matrix
| CLI | storage-api | Digest SHA-256 | Gateway | Direct container | TUS session |
|---|---|---|---|---|---|
| 2.109.1 | v1.62.5 | 1dbe962d9862ef12e20357f9d7ba5431989c1daf4a556d6cb20ee4efd1c57320 |
HTTP 400, invalid_compact_jws |
HTTP 400, invalid_compact_jws |
not created |
| 2.109.0 | v1.61.7 | 7dae5013474c1b5f816d138605e33434d83b87df1716032cf588a15561dcd937 |
HTTP 400, invalid_compact_jws |
HTTP 400, invalid_compact_jws |
not created |
Security
No token, local key, signed URL, object path, connection string, or production data is attached. The reproducer uses only isolated local stacks and temporary private buckets.
Additional context
CLI 2.109.1 was the latest stable official release observed during preparation. CLI 2.109.0 was the immediately previous stable release tested.
The behavior blocks local TUS integration tests. This report does not claim that hosted Supabase is affected and does not assume an internal cause.
Could you confirm whether this is a Storage bug or an incompatible local-stack configuration, and advise which local CLI/Storage combination should accept its own signed upload token?
Reproducer
A sanitized minimal reproducer package is available on request. It contains the two-version matrix, the minimal Storage/TUS request, sanitization and secret-verification scripts, historical validated results, and security notes.
- Dominant language
- TypeScript
- Stars
- 1.3k
- Forks
- 314
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 89
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from supabase/storage
-
S3 HEAD/GET overwrite case-insensitive user metadata collisionsPossibly taken @ferhatelmas claimed this 18 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
supabase/storage#1461 · 1 assignee ·
Maintainers usually reply within 1 day
-
The sample application in storage article points to wrong URLMay be free again @prasadf18 claimed this 198 days ago, and no pull request is open. Opendocumentation
Difficulty 1/5 Under an hour Newbie friendliness 62/100
supabase/storage#557 · 1 comment ·
Maintainers usually reply within 1 day
-
Count S3 Vector key length by Unicode characterPossibly taken @hsusul claimed this 5 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 35/100
Maintainers usually reply within 1 day
-
S3 PutObject ignores Content-MD5 integrity checksPossibly taken @ferhatelmas claimed this 5 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 70/100
supabase/storage#1561 · 1 assignee ·
Maintainers usually reply within 1 day
-
S3 DeleteObjects omits delete-marker metadata from successful versioned deletesPossibly taken @hsusul claimed this 6 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 35/100
Maintainers usually reply within 1 day
All issues in supabase/storage
Similar issues
-
freshness freshness:observed-only
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
thoroc/context-radar#282 ·
-
bug P2 rust
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
area: web
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
gabe-santana/arkdraw#25 ·
-
bug require-triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
expressjs/expressjs.com#2549 · 1 reaction ·
Maintainers usually reply within 1 day
-
bug good first issue hacktoberfest
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
codercops/discord-bot#101 · 1 comment ·
Maintainers usually reply within 1 day