Binance error -1021: timestamp for this request is outside the recvWindow

Jun 07, 20265 min read

Share|

Category:AutomationCrypto

Binance error -1021: timestamp for this request is outside the recvWindow

When your trading bot flips from working to "timestamp for this request is outside the recvWindow": why Binance rejects valid signatures after clock drift, and the time calibration that prevents -1021.

Free download: Timestamp drift runbook + logging schema. Jump to the download section.

Binance error -1021 is the single most common reason a trading bot that has been running fine for hours suddenly starts rejecting all signed requests.

The message says "Timestamp for this request is outside the recvWindow." In practice, it means your server clock has drifted outside Binance's acceptable time window since you last synced NTP.

It is not a bug in your signing code. It is not a Binance outage. Your clock is off. The fix is NTP, not code.

This post sits in the Crypto Automation hub and the Crypto Automation category.
If you only do three things
  • Sync NTP every 5-15 minutes (or use systemd-timesyncd/chrony). PC motherboards drift 1-5 seconds per day under load.
  • Set recvWindow to 5000 (5 seconds) as a safety buffer, not 5000 milliseconds exactly—use the full 5000ms value. Do not reduce it below 1000 unless you control both sides of the clock.
  • On -1021, stop retrying signed requests immediately. Fix the clock, then resume. Retrying with a drifting clock makes things worse.

Fast triage table (what to check first)

SymptomLikely causeConfirm fastFirst safe move
-1021 on all signed endpoints, started suddenlySystem clock drifted out of syncCompare date +%s with Binance server time via GET /api/v3/timeSync NTP immediately; stop retries until clock is stable
-1021 only on some instances, not othersPer-instance clock drift (uneven NTP sync)Compare timestamps across instances at the same secondFix NTP config; add clock monitoring per instance
-1021 intermittently, not all requestsrecvWindow too small; clock jitter (micro-drifts between requests)Check recvWindow setting; log timestamp sent vs Binance timeIncrease recvWindow to 5000; check NTP sync interval
-1021 immediately after deployContainer/VM clock not synced at bootCheck clock on fresh boot; some base images have no NTPAdd NTP sync to boot script; use date in health check
-1021 + 401 (signature invalid)Clock drift AND bad secret/key rotationBoth errors appear together; one caused by time, other by keyFix clock first; then verify signing key

What -1021 actually means

Binance requires every signed request to include a timestamp parameter within recvWindow milliseconds of Binance's server time.

code
GET /api/v3/order?symbol=BTCUSDT&side=BUY&type=LIMIT&timestamp=1717000000000&recvWindow=5000&signature=...
                                            ^^^^^^^^^^^^^^^^^^
                                            Must be within recvWindow of Binance time

If server_time - client_timestamp > recvWindow, Binance returns -1021.

The default recvWindow is 5000ms, but many clients set it smaller for "tighter security." The tradeoff is that tight windows break on any clock jitter—even 1-2 seconds of drift kills all signed requests.

RecvWindow is not a security feature for most users. It is a tolerance window for clock synchronization. Setting it too small is premature optimization that causes preventable incidents.


Why bots get -1021 after working for hours

Clock drift is cumulative. A machine with a typical motherboard real-time clock can drift 1-5 seconds per day. Under load, heat, or virtualization, drift accelerates.

Your bot starts with a synced clock. It signs requests correctly for hours. Then drift accumulates past the recvWindow threshold, and every signed request starts returning -1021.

This is why -1021 appears "suddenly" after hours of correct operation. The clock did not jump. It drifted steadily until it crossed the threshold.

Common drift scenarios

EnvironmentTypical drift rateTime to -1021 (recvWindow 5000)
Bare metal, good RTC0.5-2 sec/day2.5-10 days
VM, moderate load2-5 sec/day1-2.5 days
Container, no NTP daemon5-30 sec/day4 hours - 1 day
Cloud instance with NTP< 0.5 sec/dayNever (NTP keeps it in check)

The fix is not increasing recvWindow to 60 seconds. The fix is NTP sync at regular intervals.


How to fix -1021

1) Check your clock right now

bash
# Get your current Unix timestamp
date +%s
 
# Compare with Binance server time
curl -s https://api.binance.com/api/v3/time | python -c "import sys,json; print(json.load(sys.stdin)['serverTime'])"

If the difference is more than your recvWindow (default 5000ms), your clock is the problem.

2) Sync NTP

bash
# Linux (immediate sync)
sudo ntpdate -u pool.ntp.org
 
# Or restart NTP service
sudo systemctl restart systemd-timesyncd
sudo systemctl restart chronyd

3) Increase recvWindow as a safety net

Set recvWindow to 5000 (the default). Do not reduce it below 1000 unless you run your own NTP infrastructure with microsecond precision.

javascript
// Binance signed request example
const timestamp = Date.now();
const recvWindow = 5000; // 5 seconds—safe default
 
const queryString = `symbol=BTCUSDT&side=BUY&type=LIMIT&timestamp=${timestamp}&recvWindow=${recvWindow}`;
const signature = crypto.createHmac('sha256', apiSecret).update(queryString).digest('hex');

4) Add clock monitoring

Log the difference between your local timestamp and Binance server time on every signed request. Set a warning threshold at 50% of recvWindow. This catches drift before it causes failures.


What NOT to do on -1021

Do not retry

Retrying a signed request with a drifting clock will keep producing -1021. Retry loops with -1021 look like abuse to Binance's monitoring. Stop, fix the clock, then resume.

Do not reduce recvWindow to "increase security"

A recvWindow of 5000 is the default for a reason. Reducing it to 1000 or 500 gains you nothing in practice—your API secret is the real security boundary—and it makes your bot fragile to normal clock jitter.

Do not hardcode timestamps or use stale values

Some bots cache the timestamp from a previous response or use the same timestamp for multiple requests. Each request must have a fresh Date.now() (or equivalent) at the time of signing.


What to log

If you cannot answer these questions after a -1021 event, you are guessing:

  • What was the clock offset (local time vs Binance server time)?
  • Was the offset growing over time (drift) or a sudden jump (NTP leap, DST, manual change)?
  • What recvWindow was configured?
  • Was -1021 happening on all instances or just one?

Log per signed request:

  • ts
  • bot_instance_id
  • exchange (binance)
  • endpoint
  • method
  • status (expected: 200, error: -1021)
  • local_timestamp_ms
  • server_timestamp_ms (from Binance time endpoint or response header)
  • offset_ms (local - server)
  • recvWindow_configured
  • ntp_last_sync_ago_seconds

Shipped asset

Download
Free

Timestamp drift prevention package: clock monitoring + NTP checklist

Clock drift detection setup, NTP configuration templates, and recvWindow tuning guide for exchange API clients.

When to use this (fit check)
  • Your bot gets -1021 (Binance) or timestamp errors on other exchanges.
  • You want NTP configuration templates and drift monitoring setup.
  • You run across multiple instances and need consistent time sync.
When NOT to use this (yet)
  • You don't log clock offset per request and cannot trend drift over time.
  • You have no ability to install/configure NTP daemons in your environment.

What you get (2 files):

  • ntp-configuration-templates.md: NTP setup for bare metal, VMs, containers, and cloud instances
  • clock-drift-monitoring-setup.md: drift detection, alerting thresholds, and dashboard queries

  • Timestamp Drift Checker — Check your clock drift against Binance, Bybit, Kraken, Coinbase, and other exchange server times.
  • Exchange Error Lookup — Look up Binance error -1021, Bybit error 10006, and 25+ exchange error codes with recovery actions.

Resources


Checklist (copy/paste)

  • NTP sync is configured and running (systemd-timesyncd, chronyd, or equivalent).
  • NTP sync interval is 5-15 minutes (default is often fine; verify with timedatectl).
  • recvWindow is set to 5000 (default) or higher—never below 1000.
  • Each signed request uses a fresh timestamp at signing time.
  • Clock offset (local vs server) is logged per signed request.
  • Alert when clock offset exceeds 50% of recvWindow.
  • -1021 is treated as a STOP rule: fix clock first, then resume.
  • Post-deploy health check includes clock sync verification.

Key takeaways

  • Binance -1021 means your request timestamp is outside the recvWindow. Usually caused by server clock drift, not a code bug.
  • Clock drift is cumulative. A bot that works for hours can fail "suddenly" when drift crosses the recvWindow threshold.
  • Sync NTP every 5-15 minutes. PC motherboards drift 1-5 seconds per day under load.
  • Keep recvWindow at the default of 5000ms. Reducing it gains nothing and makes your bot fragile.
  • Never retry -1021. Fix the clock first, then resume signed requests.
  • Log clock offset per request and alert before drift causes failures.

Recommended resources

Download the shipped checklist/templates for this post.

On-call runbook for signature error incidents. Logging schema makes clock drift diagnostics fast. Know what to check in minutes, not hours.

resource

Related posts

Next step

Exchange API reliability, rate limiting, timestamp drift, and bot architecture patterns.

Explore Crypto Automation →