What is the ExpiredToken error with S3 signed URLs and how to avoid it

Author's image
Tamás Sallai
1 min
Photo by Aaron Burden on Unsplash

S3 signed URLs allow implementing file downloads in a serverless environment. In a nutshell, it works by:

  • the user wants to download a file
  • the backend signs a URL
  • the user then uses the URL to download the file directly from S3

A common misconception is that the URL is a simple link to a file. But it's a bit more complicated than that.

A signed URL is "X is doing Y", where:

  • X is an identity, usually a Lambda execution role, but can be an IAM user or other roles
  • Y is an action, in this case "get this object from this S3 bucket"

The signature has an expiration time and it gives a "Signature expired" error when used after that.

https://terraform-....s3.eu-central-1.amazonaws.com/file1?
	x-id=GetObject&
	X-Amz-Date=20230808T074548Z&
	X-Amz-Expires=900&
	...

But the identity itself can also expire. IAM roles give temporary credentials that can only be used up until they expire.

{
    "Credentials": {
        "SecretAccessKey": "...",
        "SessionToken": "...",
        "Expiration": "2016-03-15T00:05:07Z",
        "AccessKeyId": "..."
    }
}

So, what happens when the signature is still valid but the credentials that signed it are expired? That's the ExpiredToken error.

How to avoid it?

Make sure that when you sign a URL then the signature expires before the credentials. In the common case of a Lambda signer that means using 15 minutes or less for the expiration.

March 12, 2025

Free PDF guide

Sign up to our newsletter and download the "Foreign key constraints in DynamoDB" guide.