Binance API error -1021: timestamp outside recvWindow
Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs.
Binance error -1021 is INVALID_TIMESTAMP, and it arrives with one of two
official messages that need opposite fixes:
- “Timestamp for this request is outside of the recvWindow.”
- “Timestamp for this request was 1000ms ahead of the server’s time.”
The first means your request was too old by the time Binance evaluated it. The
second means it was dated in the future. Read msg before changing
anything — the most common “fix” for the first message, raising
recvWindow, does nothing at all for the second.
Both messages are documented for Spot and for USDⓈ-M futures, under the same code. Why exchanges put a timestamp inside the signature in the first place is covered in clock sync and timestamp errors; this page is about getting from the error to the fix.
What this error actually means
Binance documents the server-side check as a single condition:
if (timestamp < (serverTime + 1 second) && (serverTime - timestamp) <= recvWindow)
That is two independent tests joined by an AND, and each one produces its own message:
| Test | Fails when | Message you get |
|---|---|---|
timestamp < serverTime + 1 second | Your timestamp is more than a second ahead of Binance’s clock | “…was 1000ms ahead of the server’s time.” |
serverTime - timestamp <= recvWindow | Your timestamp is older than recvWindow when the request is evaluated | “…is outside of the recvWindow.” |
recvWindow appears only in the second test. No value of it can rescue a
request that is stamped too far in the future. That single observation settles
most of the confusion around this code.
The window itself:
- Spot:
recvWindowis optional, defaults to 5000 ms, maximum 60000 ms, and accepts up to three decimal places. Binance recommends 5000 or less.timestampmay be sent in milliseconds or microseconds. - USDⓈ-M futures:
recvWindowdefaults to 5000 ms. We did not find a stated maximum on the futures General Info page, so do not assume the Spot 60000 ms ceiling carries over. We also did not find microseconds mentioned for futures timestamps.
The usual cause: “outside of the recvWindow”
The request aged past the window between the moment you stamped it and the moment Binance checked it. In practice that happens in one of four ways, and the symptom pattern tells you which.
1. Your clock is behind Binance’s. Every signed request fails, every time, while unsigned market-data calls keep working. This is the clean case: nothing in your code changed, the machine’s clock drifted. Virtual machines after suspend and minimal cloud images without time sync running are the usual suspects.
2. The timestamp was generated too early. The request was stamped, then sat somewhere — a client-side queue, a rate limiter waiting for budget, a backoff before a retry — and only then went out. The symptom is intermittent failure that correlates with load. Your clock is fine; your stamp is stale.
3. A retry re-sent the original signed request. A variant of the above that deserves its own line. The first attempt timed out; the retry reuses the already-signed query string, so it carries a timestamp from several seconds ago. Re-stamp and re-sign on every attempt. If the request places an order, do not retry it at all until you have checked whether the first one landed — see retrying a failed order is not safe.
4. Seconds instead of milliseconds. A Unix time in seconds read as milliseconds is a date in January 1970. It fails the age test by decades, on every request, with the “outside” message. Easy to spot once you log the value you sent.
Fix them in that order: sync the clock, move timestamp generation to
immediately before signing, re-sign on retry, check the unit. Only after all
four is it reasonable to consider a larger recvWindow — and then as a
deliberate trade of replay protection for tolerance on a genuinely slow route,
not as a way to hide drift.
The other message: “1000ms ahead of the server’s time”
Your request claims to have been created more than a second in Binance’s
future. There is no window to widen: the check is fixed at one second and
independent of recvWindow.
In practice the causes are:
- Your clock runs fast. A manual clock change, a VM that resumed with a wrong guest clock, or a host with a misconfigured time source.
- A “safety margin” added in code. Someone met the first message, added a second or two to the timestamp to get past it, and moved the problem to the other side of the check. Look for any arithmetic on the timestamp.
- A measured offset applied with the wrong sign, or applied after the clock was corrected. Compensating for drift in code is fragile for exactly this reason — once the clock is fixed, the compensation becomes the error.
- A unit larger than the endpoint expects. A value in a finer unit than the endpoint accepts reads as a time far in the future. On Spot, where microseconds are documented as accepted, this is less likely; elsewhere it is worth checking.
The fix is always the same: remove any arithmetic on the timestamp, fix the machine’s clock, and send the raw current time.
How to confirm which one you have
Step 1 — read msg. It is one of the two strings above. That alone splits
the problem in half.
Step 2 — measure your offset. Compare your local clock against Binance’s
server time (the server-time endpoints are listed in
clock sync and timestamp errors) and log the
difference as local − server:
| Measured offset | Message you should be seeing | What to fix |
|---|---|---|
| More than about +1000 ms | “…ahead of the server’s time.” | Clock running fast, or code adding to the timestamp |
Negative, larger than your recvWindow | “…outside of the recvWindow.” | Clock running slow |
| Small, yet “outside” still appears | “…outside of the recvWindow.” | Stale stamp: queueing, backoff, or a re-sent signed request |
| Enormous and negative | “…outside of the recvWindow.” | Seconds sent where milliseconds are expected |
Step 3 — log the timestamp you actually sent next to the time the response arrived. If the gap between them is large, the delay is in your pipeline or the network, not the clock.
Where it sits among Binance’s auth-adjacent errors
Because the timestamp is inside the signed payload, clock problems are easy to
mistake for signing problems. They are not reported the same way. A timestamp
failure is -1021; a signature mismatch is
-1022; a malformed key is
-2014; a refused key, IP or permission is
-2015. If you have -1021, stop reading your
HMAC code.
For automation, treat -1021 as a hard failure rather than something to retry
through. The request is refused, retrying it unchanged fails again, and a retry
loop on a clock problem only spends rate limit. Classification of this kind is
laid out in error handling patterns for trading APIs.
FAQ
Does increasing recvWindow fix Binance error -1021?
Only for the “outside of the recvWindow” message, and only when the delay is
genuine network latency. It cannot fix “1000ms ahead of the server’s time”,
because that check is fixed at one second and does not involve recvWindow.
Fix the clock and the timestamp generation first.
What is the maximum recvWindow on Binance?
On Spot, recvWindow defaults to 5000 ms and has a documented maximum of
60000 ms. On USDⓈ-M futures it also defaults to 5000 ms, but we did not find a
stated maximum on the futures General Info page, so do not assume the Spot
figure applies there.
Why do I only get -1021 on retries?
Most likely the retry re-sends a request that was signed for the first attempt, so its timestamp is already seconds old. Generate a fresh timestamp and a fresh signature for every attempt. For order placement, check whether the first attempt went through before sending anything again.
Is -1021 the same on Binance futures and spot?
Yes in structure. USDⓈ-M futures documents the same code, the same two messages
and the same check: a timestamp more than 1000 ms ahead of server time, or older
than recvWindow, is rejected. The difference is the window’s documented
ceiling, which is stated for Spot and which we did not find for futures.