How to fix RequestTimeTooSkewed in AWS S3
What the error means
Every SigV4 request carries a timestamp, either the X-Amz-Date header or the X-Amz-Date query parameter on presigned URLs. S3 rejects a request when that time is more than 15 minutes away from its own clock:
`xml
<Error>
<Code>RequestTimeTooSkewed</Code>
<Message>The difference between the request time and the current time is too large.</Message>
<RequestTime>20261016T091500Z</RequestTime>
<ServerTime>2026-10-16T10:02:11Z</ServerTime>
...
</Error>
`
Start by comparing RequestTime with ServerTime. How far apart they are usually tells you the cause:
- An exact number of hours apart (1h, 5h, 8h): a time-zone bug. Local time was written as if it were UTC.
- A few minutes to an hour apart: the machine's clock has drifted.
- Days apart, or always the same value: a hardcoded or cached timestamp.
Step 1: Fix the machine's clock
Sync the clock with NTP on whatever machine signs the request:
- Windows: check the time zone first (Settings → Time & language). Then run
w32tm /resyncfrom an elevated prompt. - Linux (systemd):
timedatectlshows whether NTP sync is active.sudo timedatectl set-ntp trueturns it on. - Linux (chrony):
chronyc trackingshows the current offset. - macOS: turn on "Set time and date automatically" in System Settings.
A wrong time zone on a fresh Windows install is a known cause. A support article from 2BrightSparks recommends checking the time zone before the clock itself.
Step 2: Check containers and VMs
A container uses its host's clock. On a laptop, Docker runs inside a VM, and that VM's clock can fall behind after the laptop sleeps. If the error only shows up in a container, compare date -u inside the container with the host. If they differ, restart the VM or Docker Desktop.
The same applies to CI runners and old on-prem servers with no NTP access. Check date -u on the machine that actually signs, not on your workstation.
Step 3: Check how your code builds the timestamp
If you sign requests yourself rather than through an SDK, the timestamp must be in UTC and in the basic ISO 8601 format:
`
20261016T100211Z
`
Common bugs:
- Formatting local time and adding a
Z. In JavaScript,new Date().toISOString()is UTC, but building the string fromgetHours()gives local time. - In Python, using
datetime.now()instead ofdatetime.now(timezone.utc). - Computing the timestamp once at startup and reusing it for every request.
- Retrying a failed request with the original signed headers instead of signing it again.
Step 4: Let the SDK correct for skew (if you can't fix the clock)
Some AWS SDKs can adjust for clock skew by reading the server's time from an error response. The JavaScript SDK v2 has a correctClockSkew option, and NetApp's knowledge base notes that SDK v3 applies the correction automatically. Treat this as a safety net. A machine with the wrong time will also break TLS checks, logs and token expiry.
Presigned URLs are different
For a presigned URL, the time is fixed when the URL is created: it's X-Amz-Date in the query string. A skewed clock on the machine that generated the URL can cause two problems:
- If the generator's clock is behind, the URL can look expired as soon as it's created.
- If it's ahead, S3 can refuse the URL because its time is in the future.
In both cases, fix the clock where the URL is generated. The clock of the person clicking the link doesn't matter.
Pitfalls
- Don't loosen anything on the AWS side. The 15-minute window can't be configured.
- Some S3-compatible services use different limits. An OpenStack Swift commit notes older Swift versions allowed only 5 minutes, so test against the real target.
Checking a timestamp quickly
We make Presign Pad, a free browser tool for SigV4 requests. Paste the RequestTimeTooSkewed error and it explains the cause in plain words. Paste a presigned URL and it shows the signing date, expiry and time left, along with warnings.