Learn / Exchange APIs

Bybit API error 10003

Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs before acting on a number.

Bybit’s 10003 means two different things depending on your account type. On classic accounts it is “Too many sessions under the same UID”. Under a Unified Trading Account on spot, it is “Your api key has expired”.

Those have nothing in common. One is a concurrency problem you fix by closing connections; the other is a credential problem you fix by issuing a new key. So the first step is not debugging — it is working out which account type you are on.

Step 1: which account type

Under UTA the derivatives equivalent of the expired-key error is 33004, also documented as “Your api key has expired”. If you are seeing 33004 anywhere in your logs, you are on UTA and 10003 on spot means the same thing.

Two related codes settle it definitively if you are unsure. They are near-mirror images and worth reading carefully:

CodeMeaning
110028“The API can only be accessed by unified account users.”
100028“The API cannot be accessed by unified account users.”

If an endpoint returns 110028, you are not on UTA. If it returns 100028, you are. The digits differ by one position, so read them carefully — this pair causes a surprising amount of confusion on its own.

If it means “your key has expired” (UTA)

Straightforward once identified. The key is no longer valid and no amount of retrying or reconnecting will change that. Issue a new one.

Worth building in afterwards:

  • Record the creation date of every key you deploy, alongside the service using it.
  • Alert before expiry rather than on it. A key that expires at 3am during a position is a worse discovery than a calendar reminder.
  • Verify at startup. A process that checks its credentials on boot fails immediately and legibly instead of at the first order.

If it means “too many sessions under the same UID” (classic)

A concurrency limit, and the causes are usually structural rather than intentional:

Connections that are not being closed. The common one. A reconnect loop that opens a new session without closing the old leaks sessions steadily until you hit the ceiling. The signature is that it appears after the process has been running a while, and goes away on restart — then comes back.

Multiple processes sharing one key. A bot, a dashboard and a notebook all authenticating with the same credentials count against the same UID. This is also why one key per consumer is worth the setup cost: the limit becomes per-purpose, and the error tells you which purpose hit it.

Development alongside production. Running a script locally while the deployed service is live, both on the same key.

Container restarts that outpace cleanup. A crash-looping container can open sessions faster than the old ones are reaped.

The fix, in order of how durable it is:

  1. Close sessions properly — ensure disconnect logic runs on every exit path, including exceptions.
  2. Separate keys by consumer.
  3. Reuse one client instance rather than constructing a new one per call.
  4. Back off on reconnect rather than retrying in a tight loop.

What it is not

Ruling these out saves time, because they produce different codes:

CodeMeaningNot 10003 because
10005“Permission denied, please check your API key permissions.”This is scope, not sessions or expiry
10010“Unmatched IP, please check your API key’s bound IP addresses.”This is IP binding
10006 (UTA)“Too many visits. Exceeded the API Rate Limit.”Rate limit, not session count
10018 (UTA)“Exceeded the IP Rate Limit.”IP-level rate limit
20003 (WebSocket)“Too frequent requests under the same session”Message rate within one session
HTTP 401Wrong key, or auth params not in the headerAuthentication, not state

The one most often confused with 10003 is 10006. Both sound like “you are doing too much”. 10003 on classic is about how many sessions exist; 10006 is about how many requests you are making. Opening fewer connections fixes one; slowing down fixes the other.

Similarly, 10006 and 10018 need different fixes despite both being rate limits: 10006 is account-level, so slow down; 10018 is IP-level, so stop sharing an address across accounts.

Preventing the classic-account version

The underlying issue is almost always session lifecycle, so:

  • Use one long-lived client per process rather than creating clients per request.
  • Make disconnection part of shutdown, and make shutdown run on exceptions.
  • Give each consumer its own key, so the ceiling is per-consumer and attribution is automatic.
  • Avoid tight reconnect loops — exponential backoff prevents a transient network problem from becoming a session exhaustion problem.

FAQ

Does Bybit error 10003 mean my API key expired?

Only under a Unified Trading Account on spot. On classic accounts it means too many sessions under the same UID, which is a connection-lifecycle problem rather than a credential one. The presence of 33004 in your logs — the UTA derivatives expired-key code — is a good indicator that you are on UTA.

How do I know whether I have a Unified Trading Account?

The clearest signal is which of 110028 and 100028 an endpoint returns. 110028 means “can only be accessed by unified account users”, so you are not on UTA; 100028 means “cannot be accessed by unified account users”, so you are. The codes differ by one digit position, so read them carefully.

What is the difference between 10003 and 10006?

On classic accounts, 10003 is about the number of concurrent sessions and 10006 is about request rate. Fewer connections fixes the first; slower requests fix the second. They can look alike because both suggest doing too much, but the remedies do not overlap.

Why did this start happening after my service had been running fine?

If it is the classic-account meaning, the usual cause is a session leak — a reconnect path that opens without closing, accumulating over hours or days. Restarting clears it and it returns, which is the diagnostic signature. If it is the UTA meaning, the key simply reached its expiry.