Is this explanation of an upload failure accurate? An S3 presigned URL appears to have two relevant expiration limits: the explicit signature lifetime defined by X-Amz-Date and X-Amz-Expires, and the expiration of the temporary AWS credentials used to create the URL. Our client only checks the signature lifetime. I had assumed that once the URL was generated, its validity was independent of the STS session that created it. Is the URL actually limited by whichever expires first?
4 Answers
Yes, the explanation is correct. When a presigned URL is created with temporary credentials, it cannot remain usable after the underlying session token expires. The URL's effective lifetime is the earlier of its configured signature expiration and the remaining lifetime of the temporary credentials.
A client-side check should account for both values rather than parsing only X-Amz-Expires. In practice, the safest approach is to have the backend generate a URL only when it has enough remaining credential lifetime, or return an expiration based on the shorter limit. Automatically refreshed SDK credentials do not guarantee that a newly generated URL will outlive the current credential session.
If long delays are important, one option is to use a tightly scoped, longer-lived identity specifically for generating these URLs. That still has S3's maximum presigned URL lifetime of seven days, and the permissions should be restricted as much as possible. For many architectures, CloudFront signed requests or a server-side upload workflow may be a better fit.
That is the concern in my case: a mobile client may wait until it has Wi-Fi, potentially for a day or more, before starting the upload. I may need a dedicated narrowly scoped signing identity or a different upload design.
This applies through the whole credential chain. Credentials obtained from a role, which was itself assumed using another temporary session, cannot extend the lifetime of that earlier session. Creating a seven-day S3 URL from credentials that expire in 15 minutes does not turn it into a seven-day credential.

For example, if the role credentials have one hour left but you request a URL that lasts four hours, the upload can still fail after that remaining hour with an invalid or expired token.