バイナンス(Binance)のAPIエラーコードは負の整数でエンコードされており、範囲は-1000から-2099までです。これらは、共通エラー (-1000 〜 -1199)、リクエストエラー (-1100 〜 -1199)、レート制限/リスク管理 (-1003/-1013)、注文エラー (-2010 〜 -2099) の4つの主要カテゴリに分類されます。本記事では、本番環境で実際に遭遇する80以上のエラーコードとその解決策を、Pythonのエラー処理ミドルウェアのコード例とともにまとめました。APIをまだ有効にしていない方は、まず バイナンス公式サイト でKYC(本人確認)を完了させてください。新規ユーザーの方は 無料登録 も可能です。
一、エラーレスポンスの構造
バイナンスAPIのすべてのエラーレスポンスは、以下の統一された形式で返されます:
{
"code": -1021,
"msg": "Timestamp for this request is outside of the recvWindow."
}
HTTPステータスコードは通常、400(ビジネスロジックエラー)または 403/429/418(ゲートウェイエラー)となります。
二、共通エラー(-1000 〜 -1099)
| エラーコード | メッセージ | 意味 | 解決策 |
|---|---|---|---|
| -1000 | UNKNOWN | 未知のエラー | リトライする。解消しない場合はカスタマーサポートへ連絡 |
| -1001 | DISCONNECTED | 内部サーバー切断 | 5秒待ってからリトライ |
| -1002 | UNAUTHORIZED | 認証エラー | X-MBX-APIKEY ヘッダーを確認 |
| -1003 | TOO_MANY_REQUESTS | レート制限超過 | Retry-After ヘッダーの秒数分待機 |
| -1006 | UNEXPECTED_RESP | 異常なレスポンス | リトライ |
| -1007 | TIMEOUT | リクエストタイムアウト | recvWindow の値を増やす |
| -1014 | UNKNOWN_ORDER_COMPOSITION | 未対応の注文組み合わせ | 注文タイプを確認 |
| -1015 | TOO_MANY_ORDERS | 注文数が上限超過 | 未約定の注文を一部キャンセル |
| -1016 | SERVICE_SHUTTING_DOWN | サービス停止中 | 復旧を待つ |
| -1020 | UNSUPPORTED_OPERATION | 未対応の操作 | ドキュメントを確認 |
| -1021 | INVALID_TIMESTAMP | タイムスタンプのズレ | NTP同期を行うか、recvWindowを増やす |
| -1022 | INVALID_SIGNATURE | 無効な署名 | 署名アルゴリズムを確認 |
主要なエラーの詳細
-1003 TOO_MANY_REQUESTS:
{"code": -1003, "msg": "Too many requests; current limit is 6000 request weight per 1 MINUTE. Please use WebSocket Streams for live updates to avoid polling the API."}
処理方法:
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
time.sleep(retry_after)
# その後リトライ
-1021 INVALID_TIMESTAMP:
{"code": -1021, "msg": "Timestamp for this request is outside of the recvWindow."}
処理方法:
# 方法1:サーバーとの時間差を同期
server_time = requests.get("https://api.binance.com/api/v3/time").json()["serverTime"]
local_time = int(time.time() * 1000)
offset = server_time - local_time # 保存しておき、毎回の署名時に加算
# 方法2:recvWindowを拡大(最大 60000)
params["recvWindow"] = 10000
-1022 INVALID_SIGNATURE:
{"code": -1022, "msg": "Signature for this request is not valid."}
主な原因:
- 署名文字列とリクエスト文字列のパラメータ順序が一致していない
- 数値パラメータを引用符(")で囲っている
- Secret Key が途切れている、または空白が含まれている
- URLエンコード方式が異なる
三、パラメータエラー(-1100 〜 -1199)
| エラーコード | メッセージ | 意味 | 解決策 |
|---|---|---|---|
| -1100 | ILLEGAL_CHARS | 無効な文字が含まれる | 入力をクリーンアップする |
| -1101 | TOO_MANY_PARAMETERS | パラメータが多すぎる | パラメータを削減する |
| -1102 | MANDATORY_PARAM_EMPTY_OR_MALFORMED | 必須パラメータの欠落/不正 | APIドキュメントを確認 |
| -1103 | UNKNOWN_PARAM | 未知のパラメータ | 不要なフィールドを削除 |
| -1104 | UNREAD_PARAMETERS | 未使用のパラメータ | 冗長なパラメータを削除 |
| -1105 | PARAM_EMPTY | パラメータが空 | 有効な値を入力 |
| -1106 | PARAM_NOT_REQUIRED | 不要なパラメータの送信 | 削除する |
| -1111 | BAD_PRECISION | 精度エラー | LOT_SIZE / PRICE_FILTER に合わせる |
| -1112 | NO_DEPTH | 板(オーダーブック)が空 | 相場の回復を待つ |
| -1114 | TIF_NOT_REQUIRED | TIF適用外 | 成行注文には timeInForce を含めない |
| -1115 | INVALID_TIF | 無効な TIF | GTC / IOC / FOK を使用 |
| -1116 | INVALID_ORDER_TYPE | 無効な注文タイプ | サポートされているタイプを確認 |
| -1117 | INVALID_SIDE | 無効な売買区分 | BUY または SELL を使用 |
| -1118 | EMPTY_NEW_CL_ORD_ID | クライアント注文IDが空 | newClientOrderId を指定するか省略 |
| -1119 | EMPTY_ORG_CL_ORD_ID | 元の注文IDが空 | キャンセル/照会時に orderId を指定 |
| -1120 | BAD_INTERVAL | K線(ローソク足)間隔が無効 | 1m/5m/15m/1h/4h/1d などを使用 |
| -1121 | BAD_SYMBOL | 無効な通貨ペア | exchangeInfo で有効性を確認 |
| -1125 | INVALID_LISTEN_KEY | 無効な listenKey | 再度 userDataStream を呼び出す |
| -1127 | MORE_THAN_XX_HOURS | クエリ対象期間が長すぎる | 複数回に分けてクエリする |
| -1128 | OPTIONAL_PARAMS_BAD_COMBO | オプションパラメータの組み合わせミス | 排他的なパラメータがないか確認 |
| -1130 | INVALID_PARAMETER | パラメータ値が無効 | 値の範囲を修正 |
| -1131 | INVALID_JSON | JSON形式が不正 | JSONの妥当性を確認 |
主要なエラーの詳細
-1111 BAD_PRECISION(非常に頻度の高いエラー):
Filter failure: LOT_SIZE
原因:数量または価格が、その通貨ペアの stepSize / tickSize に適合していません。
# 正しい方法:取引ルールを確認した後に四捨五入/切り捨て
import math
def get_filters(symbol: str) -> dict:
r = requests.get("https://api.binance.com/api/v3/exchangeInfo",
params={"symbol": symbol}).json()
return {f["filterType"]: f for f in r["symbols"][0]["filters"]}
def round_step(value: float, step: float) -> float:
return math.floor(value / step) * step
filters = get_filters("BTCUSDT")
step_size = float(filters["LOT_SIZE"]["stepSize"]) # 例: 0.00001
tick_size = float(filters["PRICE_FILTER"]["tickSize"]) # 例: 0.01
min_notional = float(filters["NOTIONAL"]["minNotional"]) # 例: 5.0
# 注文前に正規化
quantity = round_step(0.0015789, step_size) # → 0.00157
price = round_step(60123.4567, tick_size) # → 60123.45
四、フィルター失敗(-1013)
-1013 INVALID_MESSAGE は、各フィルター(filter)とともに具体的な原因を返します:
| フィルタータイプ | 意味 | 解決策 |
|---|---|---|
| PRICE_FILTER | 価格が tickSize に適合しない | tickSize 単位で丸める |
| LOT_SIZE | 数量が stepSize に適合しない | stepSize 単位で丸める |
| MIN_NOTIONAL | 注文総額が低すぎる(<5 USDT 等) | 数量を増やす |
| NOTIONAL | 名目価値が不適合 | MIN_NOTIONAL と同様 |
| PERCENT_PRICE | 価格の乖離が大きすぎる | 市場価格に近づける |
| MARKET_LOT_SIZE | 成行注文の数量が不適合 | 成行注文のルールに合わせる |
| MAX_NUM_ORDERS | 通貨ペアごとの待機注文数上限超過 | 既存注文をキャンセルしてから発注 |
| MAX_NUM_ALGO_ORDERS | アルゴリズム注文上限超過 | 一部のストップ注文をキャンセル |
五、注文エラー(-2010 〜 -2099)
| エラーコード | メッセージ | 意味 | 解決策 |
|---|---|---|---|
| -2010 | NEW_ORDER_REJECTED | 注文拒否 | 具体的な msg フィールドを確認 |
| -2011 | CANCEL_REJECTED | キャンセル拒否 | 注文が既に約定している可能性 |
| -2013 | NO_SUCH_ORDER | 注文が存在しない | orderId を確認 |
| -2014 | BAD_API_KEY_FMT | Keyの形式エラー | 64文字であることを確認 |
| -2015 | REJECTED_MBX_KEY | Key/IP/権限の不一致 | ホワイトリストと権限を確認 |
| -2016 | NO_TRADING_WINDOW | 取引時間外 | 通貨ペアがメンテナンス中など |
| -2018 | BALANCE_NOT_SUFFICIENT | 残高不足 | 入金するか数量を減らす |
| -2019 | MARGIN_NOT_SUFFICIENT | 証拠金不足 | レバレッジを下げるか証拠金を追加 |
| -2020 | UNABLE_TO_FILL | 約定不能 | 指値価格の調整 |
| -2021 | ORDER_WOULD_IMMEDIATELY_TRIGGER | 即時トリガーされる注文 | ストップ価格を調整 |
| -2022 | REDUCE_ONLY_REJECT | 注文(Reduce Only)拒否 | ポジションの方向を確認 |
| -2023 | USER_IN_LIQUIDATION | 強制清算中 | 清算の終了を待つ |
| -2024 | POSITION_NOT_SUFFICIENT | ポジション不足 | 指定数量の決済が不可 |
| -2025 | MAX_OPEN_ORDER_EXCEEDED | 待機注文数上限超過 | 古い注文をキャンセル |
| -2026 | REDUCE_ONLY_ORDER_TYPE_NOT_SUPPORTED | タイプがReduce Only未対応 | 成行または指値に変更 |
| -2027 | MAX_LEVERAGE_RATIO | レバレッジ上限超過 | レバレッジを下げる |
| -2028 | MIN_LEVERAGE_RATIO | レバレッジが低すぎる | 引き上げる |
主要なエラーの詳細
-2010 NEW_ORDER_REJECTED(最も一般的):
msg フィールドに具体的な原因が示されます:
"Account has insufficient balance for requested action"→ 残高不足"Order would immediately match and take"→ 指値注文が即座に約定(LIMIT_MAKER モード時)"Filter failure: LOT_SIZE"→ 数量がステップサイズに適合しない"Filter failure: PERCENT_PRICE"→ 価格の乖離が大きすぎる
def place_order_safely(symbol, side, qty, price):
try:
return client.create_order(
symbol=symbol, side=side, type="LIMIT",
timeInForce="GTC", quantity=qty, price=price
)
except BinanceAPIException as e:
if e.code == -2010:
if "insufficient balance" in e.message:
return {"error": "残高不足"}
if "Filter failure: LOT_SIZE" in e.message:
return {"error": "数量精度エラー。stepSize 単位で修正が必要"}
raise
-2015 REJECTED_MBX_KEY:
以下の3つのサブ原因が考えられます(メッセージ内容から判断):
- API Key の形式エラー:64文字の長さを確認
- IP がホワイトリスト外:バイナンスにログインして更新
- 権限が有効でない:例:/fapi/ を呼び出しているが「Enable Futures」にチェックがない
六、リスク管理関連のエラー
| エラーコード | メッセージ | 意味 | 解決策 |
|---|---|---|---|
| -4001 | PRICE_LESS_THAN_ZERO | 価格が負数 | パラメータを確認 |
| -4002 | PRICE_GREATER_THAN_MAX_PRICE | 価格が上限超過 | 価格を下げる |
| -4003 | QTY_LESS_THAN_ZERO | 数量が負数 | 正の数に変更 |
| -4004 | QTY_LESS_THAN_MIN_QTY | 数量が最小値未満 | LOT_SIZE を参照 |
| -4005 | QTY_GREATER_THAN_MAX_QTY | 数量が上限超過 | 分割して発注 |
| -4006 | STOP_PRICE_LESS_THAN_ZERO | ストップ価格が負数 | 修正する |
| -4164 | MIN_NOTIONAL | 名目額が 5 USDT 未満 | 数量を増やす |
| -5021 | FOK_ORDER_REJECT | FOK 注文拒否 | 流動性不足。GTC に変更 |
| -5022 | GTX_ORDER_REJECT | GTX(Post Only)拒否 | 市場価格が変動し、メイカー注文不可 |
七、统一エラー処理ミドルウェア(Python)
import time
import requests
from typing import Optional
class BinanceAPIError(Exception):
def __init__(self, code: int, msg: str, raw: dict):
self.code = code
self.msg = msg
self.raw = raw
super().__init__(f"Binance {code}: {msg}")
def handle_response(response: requests.Response) -> dict:
data = response.json()
if "code" in data and data["code"] < 0:
raise BinanceAPIError(data["code"], data.get("msg", ""), data)
return data
def request_with_recovery(method, url, **kwargs) -> Optional[dict]:
for attempt in range(5):
try:
r = requests.request(method, url, **kwargs)
if r.status_code == 429:
retry_after = int(r.headers.get("Retry-After", 60))
print(f"レート制限。 {retry_after}秒待機")
time.sleep(retry_after)
continue
if r.status_code == 418:
raise SystemExit("IPがブロックされました。プログラムを終了します。")
data = handle_response(r)
return data
except BinanceAPIError as e:
if e.code == -1021:
print("タイムスタンプのズレ。再同期します。")
# 時間同期後にリトライ
continue
if e.code in (-1001, -1006, -1007):
wait = 2 ** attempt
print(f"一時的エラー {e.code}。 {wait}秒後にリトライ")
time.sleep(wait)
continue
# リトライ不可のビジネスエラーはそのままスロー
raise
return None
八、よくある質問 FAQ
Q1: エラーコード -1021 が頻繁に発生します。どうすればよいですか?
A: システムクロックの問題です。Linux の場合は chronyd を有効にします:
sudo systemctl enable chronyd
sudo chronyc sources -v # 同期ソースの確認
Windows の場合は、コントロールパネル → 日付と時刻 → インターネット時刻 → time.windows.com と同期します。
Q2: -1015 TOO_MANY_ORDERS が表示される原因は何ですか?
A: 単一通貨ペアの未約定待機注文数が 200(現物)または MAX_NUM_ORDERS フィルターで設定された上限を超えています。価格から遠い注文を一部キャンセルしてください。
Q3: -2015 で権限と IP を確認しましたが間違いありません。なぜエラーになりますか?
A: 現物(Spot)用の Key を先物(Futures)ドメイン(fapi.binance.com)で使用していないか、またはその逆を確認してください。現物と先物では必要な権限が異なります。同じキーでも「Enable Futures」にチェックが入っていないと、先物インターフェイスには使用できません。
Q4: ログにすべてのエラーコードを記録するには?
A: ミドルウェア層をカプセル化し、エラーコードごとに統計を取ります:
from collections import Counter
error_counter = Counter()
def log_error(code: int):
error_counter[code] += 1
if error_counter[code] > 100:
alert(f"エラー {code} が {error_counter[code]} 回発生しました。システム問題の可能性があります。")
Q5: -1013 と -2010 の違いは何ですか?
A: -1013 はフィルターエラー(パラメータが取引ルールに適合しない)、-2010 は注文拒否(ビジネスロジック層による拒否、原因は msg に記載)です。-1013 は通常、クライアント側で事前に計算することで回避可能ですが、-2010 は市場の状態(残高、スリッページ、リスク管理)に依存することが多いです。
エラーコードのリストを確認したら、カテゴリナビ に戻って「API連携」カテゴリの他の技術トピックをチェックしましょう。