SignatureDoesNotMatch The request signature we calculated does not match the signature you provided. Check your key and signing method. /jobs/imports/uploads/01K9E0WRQT8P0DM5GX65NZWXB2.csv 1762481194277975954 ``` What could be wrong? I’m familiar with presigned URLs but new to Tigris."> Presigned PUT Fails With 403 - Tigris - LLM Cache

Presigned PUT Fails With 403 - Tigris

Presigned PUT Fails With 403

Hi,

I am creating pre‑signed PUT URLs in my app and getting 403 Forbidden errors.

When creating URLs via the Tigris dashboard they look like:

https://files.allaboutholes.vip/import-jobs.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Date=20251107T020219Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=...

When creating URLs via the application code below I get this shape:

const endpoint = 'https://fly.storage.tigris.dev';
const bucketName = 'holehub-dev';
const forcePathStyle = false;
const deleteAfter = new Date(Date.now() + 1000 * 60 * 60);

const s3Client = new S3Client({
  region: 'auto',
  endpoint,
  credentials: { accessKeyId, secretAccessKey },
  forcePathStyle,
});

const signedUrl = await getSignedUrl(
  s3Client,
  new PutObjectCommand({
    Bucket: bucketName,
    Key: '/jobs/imports/uploads/01K9E0WRQT8P0DM5GX65NZWXB2.csv',
    Expires: deleteAfter,
    ContentLength: fileSize,
  }),
  { expiresIn: 3600 },
);

const s3Client = new S3Client({ region: 'auto', endpoint, credentials: { accessKeyId, secretAccessKey }, forcePathStyle, });

Resulting URL:

https://holehub-dev.fly.storage.tigris.dev/jobs/imports/uploads/01K9E0WRQT8P0DM5GX65NZWXB2.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=...&X-Amz-Date=20251107T020358Z&X-Amz-Expires=3600&X-Amz-Signature=...&X-Amz-SignedHeaders=host&x-id=PutObject

The dashboard‑generated URL works, but the S3 client‑generated one returns:

HTTP/1.1 403 Forbidden
Content-Length: 433
Content-Type: application/xml
...

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>SignatureDoesNotMatch</Code>
  <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
  <Resource>/jobs/imports/uploads/01K9E0WRQT8P0DM5GX65NZWXB2.csv</Resource>
  <RequestId>1762481194277975954</RequestId>
</Error>
HTTP/1.1 403 Forbidden
Content-Length: 433
Content-Type: application/xml
...

What could be wrong? I’m familiar with presigned URLs but new to Tigris.