SignatureDoesNotMatch Error When Using Uppy Companion with Supabase S3 Endpoint
Bug report
- [x] I confirm this is a bug with Supabase, not with my own application.
- [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
When using Supabase's S3-compatible storage with Uppy Companion (https://uppy.io/docs/companion), file uploads fail with the following error:
SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
This occurs despite correct credentials and endpoint configuration.
When using AWS s3 endpoint, this configuration is working fine. For supabase uploads, I am only updating the access key, secret, path style option and endpoint url.**
To Reproduce
Steps to reproduce the behavior, please provide code snippets or a repository:
- Set up Uppy Companion to use Supabase's S3-compatible storage:
- S3 endpoint: https://ksdkkjdflkdiqmcvolalksk.supabase.co/storage/v1/s3
- Bucket name: my-uploads
- Region: ap-southeast-2
- Configure Companion with the following environment variables:
COMPANION_AWS_KEY=xxxx
COMPANION_AWS_SECRET=xxx
COMPANION_AWS_BUCKET=my-uploads
COMPANION_AWS_REGION=ap-southeast-2
COMPANION_SELF_ENDPOINT=https://uploads.example.com/companion
COMPANION_UPLOAD_URLS=https://uploads.example.com
- Configure tusd (https://github.com/tus/tusd) as Tus server with resumable uploads:
- Enter credentials and region information:
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
export AWS_REGION=ap-southeast-2
- Run tusd:
- tusd -upload-dir=/home/ec2-user/data -s3-endpoint=https://ksdkkjdflkdiqmcvolalksk.supabase.co/storage/v1/s3 -s3-bucket=uploads -behind-proxy
- Start uppy with the following configuration:
"server": {
"host": "uploads.example.com",
"protocol": "https"
},
"corsOrigins": ["*"],
"sendSelfEndpoint": "https://uploads.example.com/companion",
"uploadUrls": ["*"],
"filePath": "/home/ec2-user/data",
"providerOptions": {},
"s3": {
"endpoint": "https://ksdkkjdflkdiqmcvolalksk.supabase.co/storage/v1/s3",
"conditions": [],
"useAccelerateEndpoint": false,
"expires": 800,
"forcePathStyle": true
},
"allowLocalUrls": false,
"logClientVersion": true
}
- Attempt to upload a file via Uppy Companion and get the error:
ERR_INTERNAL_SERVER_ERROR: s3store: unable to create multipart upload:
operation error S3: CreateMultipartUpload, https response error StatusCode: 403, RequestID: , HostID: , api error SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
Expected behavior
The file upload should succeed with a valid signature calculated for the Supabase S3-compatible endpoint.
System information
- OS: Amazon Linux 2 on an EC2 instance
- Browser (if applies): N/A
- Version of Node.js: 18.x
Any update to this issue? We're experiencing similar issue with it supabase S3 endpoint:
An error occurred (SignatureDoesNotMatch) when calling the PutObject operation: The request signature we calculated does not match the signature you provided. Check your key and signing method.
same error on PutObject operations.
aws s3 cp ... fails on the above
aws s3 ls .... passes correctly (so credentials are valid)
Hi, I've moved this issue over from the supabase repo as its storage related.
Hi, I've moved this issue over from the supabase repo as its storage related.
@Hallidayo Not sure if this is the correct place either though. Seems to be a core/backend storage issue, not specifically related to storage-js (or any other client for that matter). I am experiencing similar issues with the signature using the aws-sdk-s3 gem in a Ruby on Rails project. In my case, I am not able to generate signed urls to link to stored objects. The issue might get less attention here, while this is quite important as it breaks a critical part of the S3 compatibility.
@w3b6x9 Could you maybe look into this or move it back to main repo please? It looks like it's a backend/core issue, not a supabase-js and/or uppy-specific one.
@Tashows this is correct, this is not a client lib issue. I moved it over to storage.
@edanweis can you still repro this issue?
I just followed your repro steps and successfully uploaded a file via uppy companion without issue, but let me know if this is still not working for you.
@itslenny In my case (and that might be the case for https://github.com/supabase/storage/issues/646 as well), Rails storage library (active_storage) adds some extra parameters to the query string for content-disposition. When I disabled them, the signature worked. The issue I referenced also mentions an extra parameter in the query, that is not s3-specific. Could this be why supabase-s3 breaks (i.e. maybe extra params are filtered out when checking the signature match)? And if so, is it valid for this to be fixed on the supabase-side?
Another relevant issue even more specific: https://github.com/supabase/storage/issues/544
--
For any other Rails developers, you can work around this by creating a new active_storage service that skips adding disposition params:
# /lib/active_storage/service/supabase_s3_service.rb
require "active_storage/service/s3_service"
module ActiveStorage
class Service::SupabaseS3Service < Service::S3Service
private
def private_url(key, expires_in:, filename:, disposition:, content_type:, **client_opts)
object_for(key).presigned_url :get, expires_in: expires_in.to_i, **client_opts
end
end
end
in your storage.yml change service: S3 to service: SupabaseS3
import (
smithymiddleware "github.com/aws/smithy-go/middleware"
)
func removeDisableGzip(stack *smithymiddleware.Stack) error {
_, err := stack.Finalize.Remove("DisableAcceptEncodingGzip")
return err
}
...
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.UsePathStyle = true
o.BaseEndpoint = aws.String(...)
o.ClientLogMode = aws.ClientLogMode(0)
o.APIOptions = append(o.APIOptions, removeDisableGzip)
})
return client
I'm also getting similar issue
i solved my issue..? for my case i got my solution from https://github.com/orgs/supabase/discussions/26806 that supabase is still using AWS SDK v1, so i downgraded some libraries to adapt this. seems some libraries are deprecating v1 support as they use v2.
Closing this as solved