📖 Guides

Interactive Brokers TWS API: 'Market Data Not Subscribed' — How to Fix Every Cause (2026)

⚠️ Disclosure: Some links on this page are affiliate links. If you sign up through them, I may earn a commission — at no extra cost to you. I only review tools I actually use.

The Error That Stops Every IB Bot Builder

You write your first reqMktData call. You connect to TWS or IB Gateway. And instead of streaming prices, you get this:

Error 354: Requested market data is not subscribed.
Delayed market data is available.

Or the even more cryptic variant:

Error 10167: Requested market data is not subscribed.
Displaying delayed market data.

I have been running a production USDJPY momentum strategy on IB Gateway for months. I have hit both of these errors — during initial setup, after account changes, and when switching between paper and live environments. Every time, the root cause was one of six specific things.

This guide covers all of them, in order of how likely they are to be your problem.

---

Quick Diagnosis: Which Error Are You Getting?

Before diving into fixes, identify your exact situation:

Error CodeMessageMost Likely Cause
354"Requested market data is not subscribed"Missing market data subscription for that exchange
10167"Requested market data is not subscribed. Displaying delayed market data"Same as 354, but TWS is falling back to delayed data
10168"Market data farm connection is inactive"TWS/Gateway not connected to data servers
2104"Market data farm connection is OK"Not an error — this is a status message confirming connection
If you are seeing 354 or 10167, keep reading. If you are seeing 10168, skip to the connection issues section.

---

Fix 1: You Actually Need a Market Data Subscription (Most Common)

This is the cause 80% of the time. Interactive Brokers requires active market data subscriptions for most exchanges — and the subscriptions you need depend on *what* you are trading.

How to Check Your Current Subscriptions

1. Log in to Client Portal

2. Go to Settings → User Settings → Market Data Subscriptions 3. You will see a list of your active subscriptions (or an empty list if you have none)

What You Need by Asset Class

US Stocks (NYSE, NASDAQ, ARCA):
SubscriptionMonthly CostWhat It Covers
US Securities Snapshot & Futures Value Bundle$10.00NYSE, NASDAQ, AMEX, ARCA — streaming L1
US Equity and Options Add-On Streaming Bundle$4.50Adds streaming (vs snapshot-only)
Total for most US stock traders$14.50Or $0 if you trade actively enough
Forex (my setup):

Here is the part that trips up a lot of algo traders: forex market data on IB is free. You do not need to subscribe to anything. IBKR provides IDEAL Pro forex quotes at no charge for funded accounts.

My Python trading bot connects to IB Gateway, calls reqMktData for USDJPY, and gets real-time streaming prices without paying for any market data subscription. Total monthly cost for forex data: $0.00.

But you still need a funded account with at least $500 USD (or equivalent).

Futures (ES, NQ, CL):
SubscriptionMonthly CostWhat It Covers
CME Market Data (Non-Professional)$1.00E-mini S&P 500, E-mini NASDAQ, Micro contracts
NYMEX Market Data$1.00Crude oil (CL), natural gas (NG)
Total for basic futures$2.00Non-professional classification required
Options:

US options data comes bundled with the US Securities Snapshot bundle ($10/mo). No separate subscription needed.

The Free Data Waiver

If you generate at least $30 USD/month in commissions, IB waives up to $30/month in market data fees. For active algo traders, this often means your data subscriptions are effectively free.

Check your commission spend: Client Portal → Reports → Activity → look at monthly commission totals.

---

Fix 2: Paper Trading Account Without Subscriptions

This catches almost every beginner.

The problem: Paper trading accounts on IB do not automatically inherit your live account's market data subscriptions. If you subscribed to US equities data on your live account but are testing your bot on a paper account, you will get error 354. The fix:

Paper accounts get free delayed data (15-20 minutes delayed) by default. To use it in your API code, you need to explicitly request delayed data:

# Python — ib_insync
from ib_insync import *

ib = IB()
ib.connect('127.0.0.1', 7497, clientId=1)  # 7497 = paper trading port

# Tell the API to accept delayed data
ib.reqMarketDataType(3)  # 3 = delayed data

contract = Stock('AAPL', 'SMART', 'USD')
ib.qualifyContracts(contract)
ticker = ib.reqMktData(contract)
ib.sleep(2)
print(ticker)

# Python — ibapi (official TWS API)
from ibapi.client import EClient
from ibapi.wrapper import EWrapper

class MyWrapper(EWrapper):
    def error(self, reqId, errorCode, errorString, advancedOrderRejectJson=""):
        print(f"Error {errorCode}: {errorString}")

    def tickPrice(self, reqId, tickType, price, attrib):
        print(f"Price: {price}")

class MyClient(EClient):
    def __init__(self, wrapper):
        EClient.__init__(self, wrapper)

app = MyWrapper()
client = MyClient(app)
client.connect("127.0.0.1", 7497, clientId=1)

# Request delayed market data
client.reqMarketDataType(3)  # 1=live, 2=frozen, 3=delayed, 4=delayed-frozen

Market data types explained:

TypeCodeDescriptionRequires Subscription?
Live1Real-time streamingYes
Frozen2Last available price when market closedYes
Delayed315-20 min delayedNo
Delayed Frozen4Last delayed price when market closedNo
Pro tip: Always call reqMarketDataType *before* your first reqMktData. If you call it after, you may need to cancel and re-request the data.

---

Fix 3: Wrong Contract Definition

The API is extremely picky about contract specifications. A slightly wrong contract will return error 354 even if your subscriptions are correct.

Common mistakes:

# WRONG — missing exchange
contract = Contract()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.currency = "USD"
# Missing: contract.exchange = "SMART"

# WRONG — wrong secType for forex
contract = Contract()
contract.symbol = "USD"
contract.secType = "STK"  # Should be "CASH"
contract.exchange = "IDEALPRO"
contract.currency = "JPY"

# CORRECT — US stock
contract = Contract()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"

# CORRECT — forex pair (how I request USDJPY)
contract = Contract()
contract.symbol = "USD"
contract.secType = "CASH"
contract.exchange = "IDEALPRO"
contract.currency = "JPY"

# CORRECT — E-mini S&P 500 futures
contract = Contract()
contract.symbol = "ES"
contract.secType = "FUT"
contract.exchange = "CME"
contract.currency = "USD"
contract.lastTradeDateOrContractMonth = "202606"  # Must specify expiry

The debug trick: Use reqContractDetails to verify IB recognizes your contract before requesting market data:

💡 Interactive Brokers

Like what you're reading? Try it yourself — this link supports ChartedTrader at no cost to you.

Open an IBKR Account →

# ib_insync
from ib_insync import *

ib = IB()
ib.connect('127.0.0.1', 7496, clientId=1)

contract = Stock('AAPL', 'SMART', 'USD')
details = ib.reqContractDetails(contract)

if details:
    print(f"Found: {details[0].contract.symbol} on {details[0].contract.exchange}")
    print(f"Market data requires: check subscriptions for {details[0].contract.primaryExchange}")
else:
    print("Contract not found — fix your contract definition first")

If reqContractDetails returns nothing, your contract definition is wrong. Fix that before troubleshooting subscriptions.

---

Fix 4: Professional vs Non-Professional Classification

This is the silent budget killer. IB classifies users as either Professional or Non-Professional for market data pricing. The difference is massive:

Data BundleNon-ProfessionalProfessional
US Securities Snapshot & Futures Value Bundle$10/mo$125/mo
CME Real-Time Data$1/mo$85/mo
NASDAQ TotalView (Level 2)$1.50/mo$25/mo
When you first open your IB account, you are asked to fill out a market data questionnaire. If you answer "yes" to any of these, IB classifies you as Professional: How to check: Client Portal → Settings → User Settings → Market Data Subscriber Status If you were wrongly classified as Professional: Contact IB support to re-classify. You may need to fill out a new non-professional questionnaire. This alone can save you $100+/month.

---

Fix 5: Exceeded Market Data Lines Limit

IB limits the number of concurrent market data lines (tickers you can stream simultaneously). The default is 100 lines for accounts generating less than $40/month in commissions.

If your bot requests data for 150 symbols, symbols beyond the limit will throw errors.

How to check your limit:

# The API does not directly report your line limit.
# But you can see it in Client Portal:
# Settings → User Settings → Market Data → Streaming Market Data Lines

How to increase it:

Workaround for bots: If you only need data for a few symbols at a time, cancel market data requests for symbols you are done with before requesting new ones:

# ib_insync — rotate through symbols
for symbol in large_symbol_list:
    contract = Stock(symbol, 'SMART', 'USD')
    ticker = ib.reqMktData(contract)
    ib.sleep(2)
    # Process data...
    ib.cancelMktData(contract)  # Free up the line

---

Fix 6: TWS/Gateway Connection and Port Issues

Sometimes error 354 is actually a connection problem masquerading as a subscription issue.

Verify your connection:
PlatformDefault Port (Live)Default Port (Paper)
TWS74967497
IB Gateway40014002
Common connection mistakes:

1. Connecting to paper port (7497/4002) when you meant live (7496/4001) — paper has no subscriptions by default

2. API connections not enabled — In TWS: Edit → Global Configuration → API → Settings → Enable ActiveX and Socket Clients 3. IB Gateway not authenticated — Gateway needs IB Key 2FA on every restart. If authentication failed silently, you will get data errors instead of connection errors.

If you are running IB Gateway for automated trading, I wrote a detailed guide on fixing IB Key 2FA issues — the most common reason Gateway fails to authenticate after a restart.

Quick connection test:

from ib_insync import *

ib = IB()
try:
    ib.connect('127.0.0.1', 4001, clientId=1)
    print(f"Connected: {ib.isConnected()}")
    print(f"Accounts: {ib.managedAccounts()}")

    # Check connection to data farms
    # If this returns empty, data farm connection failed
    ib.reqMarketDataType(1)
    contract = Forex('USDJPY')
    ticker = ib.reqMktData(contract)
    ib.sleep(3)

    if ticker.last != ticker.last:  # NaN check
        print("No data received — check data farm connection")
    else:
        print(f"USDJPY: {ticker.last}")
except Exception as e:
    print(f"Connection failed: {e}")
finally:
    ib.disconnect()

---

My Production Setup: What Actually Works

Here is the exact configuration running my USDJPY momentum strategy on IB Gateway, with zero market data errors for months:

Environment: Startup sequence in my trading daemon:

import asyncio
from ib_insync import *

async def connect_and_verify():
    ib = IB()
    await ib.connectAsync('127.0.0.1', 4001, clientId=1)

    # Always set market data type explicitly
    ib.reqMarketDataType(1)  # 1 = live streaming

    # Verify data connection with a known contract
    contract = Forex('USDJPY')
    ib.qualifyContracts(contract)
    ticker = ib.reqMktData(contract)

    await asyncio.sleep(3)

    if ticker.last != ticker.last:  # NaN = no data
        raise RuntimeError("Market data not flowing — check Gateway auth and subscriptions")

    print(f"Data OK — USDJPY: {ticker.last}")
    return ib

Key lessons from production:

1. Always call reqMarketDataType before any data request, every time you connect 2. Verify data is actually flowing with a canary request (I use USDJPY since it is free) 3. If Gateway restarts, re-authenticate IB Key 2FA *before* your bot reconnects — otherwise you get silent data failures 4. Use clientId consistently — if another process already connected with the same clientId, your data requests may not work

---

The Complete Troubleshooting Checklist

Run through this when you hit "market data not subscribed":

Nine times out of ten, the fix is one of the first three items on this list.

---

Still Stuck? Three More Things to Try

1. Restart TWS/Gateway completely. Not just reconnect your bot — close TWS/Gateway, re-authenticate with IB Key, and start fresh. Stale sessions can cause phantom data errors. 2. Check IB system status. Occasionally IB's data farms have outages. Check the IB System Status page before spending hours debugging your code. 3. Call IB support. If your subscription looks correct but data still will not flow, IB support can check if there is a backend issue with your account's data entitlements. This has happened to me once — a subscription was marked as active in Client Portal but not actually provisioned on the backend. Support fixed it in minutes.

---

What to Read Next

If you are building an automated trading system on Interactive Brokers, these guides cover the rest of the stack:

*I run a live USDJPY momentum strategy on Interactive Brokers. If you are building your own algo trading system, IBKR's referral program gives new accounts up to $1,000 in IBKR stock — which helps offset those first few months of market data subscriptions.*

---

Just Signed Up? Here's What to Do Next

Interactive Brokers: Follow our IBKR setup guide — application, funding (you can get up to $1,000 in IBKR stock), and your first trade.

---

Interactive Brokers

Ready to get started? Use the link below — it helps support ChartedTrader at no cost to you.

Open an IBKR Account →
📈

About the author

I'm a systematic trader running live strategies on IB (USDJPY momentum) and Hyperliquid (crypto perps). Every tool reviewed here is something I've used with real capital. Questions? Reach out.

📚 Related Articles

📖 Guides

Interactive Brokers Market Data Subscription: Which One Do You Actually Need? (2026 Guide)

Interactive Brokers has dozens of market data subscriptions and most traders overpay. Here's exactly which bundles you need for forex, stocks, futures, and options — plus how to get them waived through commission credits.

April 5, 2026 ⏱ 11 min read
📖 Guides

OKX Equity Perpetual Swap Funding Rate: How Much Does It Cost to Hold TSLA and NVDA Overnight? (2026 Guide)

OKX equity perpetual swaps let you trade TSLA, NVDA, and 17+ stocks 24/7 but funding rates add up. Real cost data, IBKR comparison, and 5 ways to minimize overnight holding fees.

April 4, 2026 ⏱ 11 min read
📖 Guides

How to Buy Bitcoin and Crypto on Interactive Brokers in Europe: Complete EEA Setup Guide (2026)

Interactive Brokers now offers crypto trading for individual investors across the EEA. Step-by-step guide to enable crypto permissions, buy your first Bitcoin, and manage digital assets alongside stocks — all from one IBKR account.

April 2, 2026 ⏱ 12 min read

📬 Get weekly trading insights

Real trades, honest reviews, no fluff. One email per week.