Amazon Web Services · api · fg-0181

S3 presigned URL expires after an hour or a few hours even though you set expiresIn to 7 days

ExpiredToken: The provided token has expired

Verified 2026-10-15 · Confirmed by 0 builders · Trust 50/100

Cause

A presigned URL is only valid while the credentials that signed it are valid. Role and STS credentials expire on their own schedule, and the URL dies with them.

Fix

Sign long-lived URLs with credentials that live as long as the URL, or keep URLs short and mint a fresh one on demand from your backend. For AssumeRole, raise the session duration if a few hours is enough.

Apply

// generate on request instead of storing the URL
app.get('/files/:key', async (req, res) => {
  const url = await getSignedUrl(s3, new GetObjectCommand({ Bucket, Key: req.params.key }), { expiresIn: 300 });
  res.redirect(url);
});

Affects: All S3 presigned URLs signed with IAM role, instance profile, ECS task role, Lambda execution role, or STS credentials; maximum is 7 days only for IAM user keys with SigV4

Sources

Have your agent know this before it fails

claude mcp add --transport http footgun https://getfootgun.com/api/mcp