Errors, pacing, limits, and diagnostics
errorEvent(reqId, errorCode, errorString, contract) carries fatal errors, request rejections, warnings, and informational farm messages. Classify by code and context; do not treat every event as a disconnect.
High-value codes
| Code | Meaning / response |
|---|---|
100 | More than 50 protocol messages/second. Slow globally; TWS may disconnect. |
101 | Market-data line limit reached. Cancel unused subscriptions or increase entitlement/boosters. |
103 | Duplicate/non-increasing order ID. Reconcile observed IDs; never reuse IDs. |
104 | Cannot modify a filled order. Reconcile fills. |
105 | Modification does not match original order identity. Restrict changes to permitted fields. |
110 | Price does not conform to minimum tick. Use market-rule increments, not only minTick. |
162 | Historical-service error/pacing/no-data family; inspect the text. |
165/166 | Historical query issue / expired-contract data unavailable. |
200 | No or ambiguous security definition. Qualify with more fields. |
201/202 | Order rejected/cancelled with reason. Persist the full message. |
354 | Missing market-data subscription. |
355/388 | Invalid order size/minimum. Read contract details. |
387 | Order type unsupported for exchange/security. |
399/400 | Generic order/algo error; retain advanced reject details and parameters. |
502 | OS could not open socket: app/port/API/trusted-IP/firewall issue. It may not appear in TWS logs. |
504 | Request attempted while not connected/ready. |
Advanced order rejects
Modern servers can provide structured advanced rejection JSON. Order.advancedErrorOverride can override specific reject tags for eligible flows. Never pass overrides generically: show the exact reject to an authorized operator, validate policy, and allowlist only understood tags. An override can bypass protections or regulatory prompts.
Request identity
IB/Client allocate request IDs. A cancel must use the live subscription object/ID pair; cancelling an unknown ID produces errors such as 300 or 366. Do not recycle IDs within a connection. Order IDs have stricter monotonic/cross-client rules than request IDs.
Limits are layered
- global outbound protocol rate: 50 messages/second documented;
Clientdefaults to 45; - market-data lines: account-based formula shared by TWS and API;
- market depth: documented limit of three distinct depth requests in the legacy code table, with duplicate-instrument nuances and entitlement changes;
- historical requests: simultaneous, duplicate, burst, and rolling-window limits;
- tick-by-tick: tied to market-data-line allowance;
- scanners, news, option calculations, fundamentals, and account subscriptions have their own server rules.
A single token bucket is necessary but insufficient. Use per-endpoint concurrency/burst controls plus a global sender budget.
Diagnostics checklist
Capture UTC timestamp, connection epoch, client ID, server version, request/order ID, account, qualified contract, parameters with secrets removed, code/message, and last-message age. Enable API logs temporarily when needed. TWS/IBG API logs conventionally rotate by client ID and weekday; copy them before rollover. Market-data logging can be enormous.
Never log credentials, Flex tokens, full account identifiers in public logs, or sensitive MiFID/advisor metadata.
Official reference: TWS API message codes.