Troubleshooting
Symptom-first fixes — connect does not list bicrypto, an empty balance with no error, a book that never populates, signature and clock rejections, XEMM that never hedges, and server instances that go straight to Crashed.
Almost every report here is one of six things, and four of them produce no error message at all — Hummingbot swallows connector import failures and balance-fetch failures by design. Start with the four commands at the bottom of this page before assuming anything.
connect does not list bicrypto
Hummingbot discovers connectors by importing them. Its discovery scans its
connector folders and imports each <name>_utils inside a bare
except ModuleNotFoundError: continue, so a connector that is absent or
unimportable is silently skipped. There is nothing in the log to read.
-
Run the installer's doctor. It reproduces exactly what discovery does, but reports the error.
python install_connectors.py /path/to/hummingbot --doctor -
Check for a nested package. If
hummingbot/connector/exchange/bicrypto/bicrypto/exists, a manual copy nested. Re-run with--clean. -
Confirm the conda environment.
No module named 'hummingbot'means the installer ran outside it —conda activate hummingbotand try again. -
Rebuild if
setup.pychanged. The installer says so when it patches it:./install && ./compile.
The installer also detects directories readable but not enterable, case-variant folder names, leftover files from older versions, locally modified files, and being pointed one level too deep or too shallow.
Not a cause: a missing __init__.py. Python namespace packages import a
directory fine without one.
create does not list bicrypto_pmm
Expected, and reinstalling will not change it. create is the Strategy V1
wizard and only ever offers V1 strategies. bicrypto_pmm is a V2 controller — a
separate system create never lists.
Start a controller through a script config that names it, then
start --v2 my-strategy.yml. The --v2 flag resolves against conf/scripts/,
not conf/controllers/; passing the controller filename produces
V2 config file not found. See Connecting a bot.
balance is empty, with no error
Hummingbot renders a failed balance fetch as an empty list rather than a message. Most common causes first:
| Cause | Fix |
|---|---|
| Funds are in the wrong wallet | The spot connector reads Funding (ECO) only; the perpetual connector reads Futures only. Transfer and retry |
| The base URL was never saved | Re-run connect bicrypto and answer Yes when it offers to replace the existing key — answering No aborts the whole prompt sequence, including the URL |
| Clock drift | Signed requests are refused outside ±10 seconds. Enable NTP on the bot's host |
The key lacks hb:read:account |
Check its scopes on the admin API Keys page |
Signature, clock and scope rejections
| Message | Cause |
|---|---|
Bad signature |
The secret does not match the key — usually a rotation applied on one side only, or whitespace pasted with the secret |
Request outside recvWindow |
The bot host's clock has drifted more than 10 seconds. The message names the direction and size; being ahead is the case people do not expect |
Replayed nonce |
Two requests reused a nonce — normally two bots sharing one key. Give each its own |
403 Insufficient API key scope |
The key lacks the scope for that call. The message names the scope required |
403 IP not allowed for this key |
The key is IP-restricted and the bot moved. Update the allowlist — an empty allowlist denies everything |
423 with a reason |
The key is disabled. The reason is whatever the operator or the customer typed |
503 Hummingbot trading is paused by the administrator |
The global kill switch is on |
503 … read-only mode |
Read-only mode is on; reads still work |
A clock rejection is recorded against the key, so it appears in that key's audit trail on the admin side. That is deliberate: drift used to leave no trace on the exchange at all, which sent people off to reinstall a connector that was fine.
SSL: "unable to get local issuer certificate"
A server certificate problem, not a connector one. Your web server is serving only the leaf certificate without its intermediate — browsers paper over that and Python does not.
openssl s_client -connect your-domain.com:443 -servername your-domain.com < /dev/nullunable to verify the first certificate confirms an incomplete chain. Serve the
full chain — with Let's Encrypt use fullchain.pem, not cert.pem.
"Bid/Ask orderbook is empty"
The strategy has no prices to quote against. Check in order:
-
The pair exists and is active.
curl https://your-domain.com/api/hb/exchange-infoand look for it insymbolswith statusTRADING. -
The market genuinely has resting orders. A market with nobody quoting it has an empty book, correctly. If you are seeding it yourself, that is what the PMM — Wide profile is for.
-
The connector is current. Re-run the installer against the checkout and restart Hummingbot. An older connector never populated the book at all, because the two steps Hummingbot's book tracker uses to hand a live message to the book were missing and Hummingbot refuses them outright when they are absent.
Orders and fills
Placed in Hummingbot, never appears on the exchange. Check the kill switch and read-only mode first — both reject placement. Then the balance in the relevant wallet, and that the size clears the market's minimum notional.
Filled on the exchange, Hummingbot never notices. Fills reach bots through the WebSocket stream. Confirm the socket is connected and check the fill-detection poll interval in Settings. Hummingbot also polls order status as a fallback, so a persistent miss on both paths points at the WebSocket connection itself.
Every order is a fraction of the size asked for, on perpetuals. Fixed. An older connector divided leveraged quantities by the leverage factor, so 1 contract at 20× opened 0.05 — and the response echoed the shrunken size back, so Hummingbot's own reconciliation agreed and never raised a discrepancy. Reinstall the kit.
XEMM is not hedging
Almost always a profitability target set below the fee-and-slippage floor, so no
level ever qualifies. Recompute it against your own fee schedule — see
Strategies. Also confirm the taker venue's own
credentials are connected inside Hummingbot: connecting bicrypto does nothing
for the hedge leg.
Server-side instances
An instance goes straight to Crashed. Press Diagnose. The reason will be one of the failed checks with the fix beside it; the most common is a Python interpreter that cannot import the checkout, which means the wrong conda environment. The card also names a probable cause from the exit itself rather than showing "exited with code 1".
"Executable not found: /…/envs/hummingbot/bin/python". The interpreter recorded on the instance is not readable from the backend. Nothing has been run at this point — the path was checked and the check failed — so it is never a connector problem, and re-running the connector installer changes nothing.
Two causes produce the identical message, because the check cannot tell them apart:
- The path is wrong. Usually a conda location that was assumed rather than
read.
conda env liston the server gives the real prefixes; conda in/optis as common as conda in a home directory. - The path is right but unreadable. Every path is resolved as the account
the backend runs as. Confirm with
sudo -u <backend-user> /path/to/python --version, and check that account can traverse each parent directory (namei -l /path/to/python).
Fix it on the instance's Python interpreter field, then press Diagnose.
Cancels fail with You must provide a buffer containing 16 bytes. That
sentence is a database driver reporting that an order id is not a UUID, and it
means the bot asked to cancel by its own client order id at a moment when the
exchange could no longer translate it.
The translation lives in Redis and nowhere else — the order tables carry no
client-order-id column — so it is lost if Redis restarts without persistence, if
the key is evicted under maxmemory, or after its seven-day expiry. A market
maker writes two such keys per placement, so on a memory-capped Redis they are
the first thing an allkeys-* policy discards:
redis-cli INFO stats | grep evicted_keys
redis-cli CONFIG GET maxmemory-policyThe exchange now answers this with a 404 naming the id rather than a 500, so the
bot stops burning seven retries per tick on it and says plainly that the order is
still live. The order is still resting and still holding funds — cancel it
from the exchange UI. Give Redis a noeviction policy, or enough memory that
these keys are never evicted, to stop it recurring.
"Failed to start strategy simple_xemm: extra inputs are not permitted." The
config being started is a script config, and the fields in it belong to a
V2 controller. simple_xemm.py is one of Hummingbot's own sample scripts and
has nothing to do with this platform — nothing here ever generates that name.
Delete that file. Do not delete the offending keys to make it load: without them
it starts on SimpleXEMMConfig's defaults, whose taker is binance_paper_trade,
and you get the unhedged shape described below without meaning to. A generated
controller config is started the way its own header says — save it as
conf/controllers/<name>.yml, create conf/scripts/<name>.yml naming
script_file_name: v2_with_controllers.py, and start that.
No module named 'hummingbot.connector.exchange.binance_paper_trade',
repeating. Your XEMM taker is a paper connector. Hummingbot's price-feed loop
imports connector names literally and never strips the _paper_trade suffix, so
that name always fails there. The error is harmless in itself — but read the next
entry, because it is telling you something that is not.
Hummingbot reports a huge fee on a partial fill. A fill of 15% of an order
showing the fee for 100% of it — 0.79 USDT on a 12 USDT trade, say. Your wallets
were always charged correctly; only what the bot was told was wrong. The
exchange records fee against the whole order, and both the connector and the
live trade stream were dividing it by the amount filled so far instead of by
the order's size, so the first fill absorbed the entire fee.
Fixed on the exchange side and in the connector kit. Update the kit
(python install_connectors.py /path/to/hummingbot) and restart the bot. It
matters beyond the display: XEMM decides whether to hold or re-quote a level
from a profitability figure computed net of that number.
Your hedge may be simulated while your maker orders are real. An XEMM preset
whose taker connector ends in _paper_trade quotes for real on this exchange and
hedges into Hummingbot's simulator. It is a supported rehearsal, and while it
runs it is an unhedged market maker: real one-sided inventory accumulates, and
the strategy's reported profit counts hedges that never happened.
Check the event_source on the fill events in your log — bicrypto is real,
*_PaperTrade is not. The instance log also carries an UNHEDGED: line at every
start, and the generated controller file a WARNING — SIMULATED HEDGE header. To
hedge for real, stop the instance and set the preset's taker to the live venue
name.
"Config password can no longer be decrypted." APP_ACCESS_TOKEN_SECRET was
rotated, which invalidates stored passwords by design. Edit the instance and
re-enter the Hummingbot config password.
A start fails on the Hummingbot config password. The panel will not overwrite
a checkout's existing conf/.password_verification, so an instance whose stored
password differs from the one that file was created with is refused rather than
locked out. Re-enter the password the checkout already uses. This is the usual
second surprise after an interpreter is corrected on a server where Hummingbot
had been started by hand.
The connector installer says HEALTHY but the panel still fails. They test
different things with different interpreters. install_connectors.py --doctor
validates the connector files against whichever python invoked it; the panel
validates the interpreter stored on the instance row. A green installer run has
never proved anything about the panel's configuration. The doctor now prints the
interpreter it used, so the two can be compared directly.
The bot starts, stays alive, and never quotes. Its market is not one the exchange lists — the connector subscribes and waits forever for a book that never arrives. Registering and starting now refuse this and list the pairs that do exist, but an install without the Ecosystem addon cannot read the market list, so the check yields nothing and the start is allowed.
An instance is killed repeatedly. Look for a memory-limit line in the logs. XEMM runs two connectors and needs roughly twice the memory of a single-pair market maker. Raise the cap if the host has headroom, and reconsider running it there at all if it does not.
Config changes appear to do nothing. Configuration is read at launch, so a running process keeps what it started with. Press Restart — that regenerates the controller YAML from the preset and relaunches.
Bots do not come back after a deploy. Check the backend log for
[HB] Hummingbot supervisor not started. The supervisor runs on the main thread
only, and its failure is deliberately non-fatal so the exchange still boots.
The whole Hummingbot admin section is empty for everyone but the owner
The section root gates on access.hb. Super Admin bypasses permission checks
entirely, so an install where nobody else can open it looks fine from the owner
account. Grant the section and the four view-level keys in Admin → Roles —
they are listed on Install and enable.
If the section is missing entirely for everyone, check the licence: /api/hb and
/api/admin/hb are both licence-enforced prefixes, so an expired or unverified
licence removes the whole surface rather than one screen.
Before opening a support ticket
These four commands answer most questions before they need asking.
# 1. Is the server side alive?
curl https://your-domain.com/api/hb/ping
# 2. Is its clock sane? Compare with your own.
curl https://your-domain.com/api/hb/time
# 3. Does the pair you want to quote exist, and does it read TRADING?
curl https://your-domain.com/api/hb/exchange-info
# 4. Is the connector install healthy?
python install_connectors.py /path/to/hummingbot --doctorInclude the output of all four, plus the last 200 lines of the Hummingbot log, when you report a problem. For a server-run instance, include the Diagnose result and the tail of the instance log instead of the fourth command.