Fulcrum silently swallows several client-facing errors, making it impossible for API consumers to distinguish "no data" or "server failure" from "limit exceeded".
1. max_history exceeded returns empty results instead of errors
When get_history encounters an address whose transaction count exceeds max_history, the client sees [] which is indistinguishable from an address with no history.
For example, querying a chipnet address bchtest:qzfxpjt3xm2rfzhxsef6f296a0zavvk6ncx7f2cnw7 with ~300k transactions against public Fulcrum servers today:
get_history: 0 items ← silent failure, should be an error
get_balance: 9,470,183,738 sats confirmed
listunspent: 1,277 utxos
The address clearly has activity but get_history returns nothing. A client has no way to know the history exceeded the limit vs. being genuinely empty (especially in the case where the current balance is zero).
The same pattern exists in listunspent and get_balance but these count UTXOs rather than transactions, so they rarely hit the limit in practice, but would also silently return empty/zero if they did.
2. max_clients_per_ip exceeded aborts the TCP connection with no explanation
When the per-IP connection limit is reached, the client sees a TCP RST with zero explanation which is ndistinguishable from a network error.
3. Excessive errors disconnect without warning
After kMaxErrorCount = 10 errors, the client is killed with no notification. The client cannot distinguish between a server crash and an intentional disconnect.
4. Global subscription limit kicks clients without notification
When max_subs is reached, clients are disconnected without any explanation.
Suggested behavior
In all four cases, the client should receive a JSON-RPC error response before being disconnected, rather than seeing silent empty data or a raw TCP reset.
1. max_history should return an error instead of empty results
{"jsonrpc": "2.0", "error": {"code": 4, "message": "History too large (limit: 125000)"}, "id": 1}
2. max_clients_per_ip should send an error before closing the connection
Rather than an immediate TCP abort, briefly accept the connection and send:
{"jsonrpc": "2.0", "error": {"code": 4, "message": "Connection limit exceeded (12 per IP)"}, "id": null}
A hard abort could still apply at some higher threshold (e.g. 2x the limit) to prevent resource exhaustion.
3. Excessive errors should notify before disconnect
{"jsonrpc": "2.0", "error": {"code": 3, "message": "Too many errors, disconnecting"}, "id": null}
4. Subscription limit should notify before kick
{"jsonrpc": "2.0", "error": {"code": 4, "message": "Subscription limit reached, disconnecting"}, "id": null}
Fulcrum silently swallows several client-facing errors, making it impossible for API consumers to distinguish "no data" or "server failure" from "limit exceeded".
1.
max_historyexceeded returns empty results instead of errorsWhen
get_historyencounters an address whose transaction count exceedsmax_history, the client sees[]which is indistinguishable from an address with no history.For example, querying a chipnet address
bchtest:qzfxpjt3xm2rfzhxsef6f296a0zavvk6ncx7f2cnw7with ~300k transactions against public Fulcrum servers today:The address clearly has activity but
get_historyreturns nothing. A client has no way to know the history exceeded the limit vs. being genuinely empty (especially in the case where the current balance is zero).The same pattern exists in
listunspentandget_balancebut these count UTXOs rather than transactions, so they rarely hit the limit in practice, but would also silently return empty/zero if they did.2.
max_clients_per_ipexceeded aborts the TCP connection with no explanationWhen the per-IP connection limit is reached, the client sees a TCP RST with zero explanation which is ndistinguishable from a network error.
3. Excessive errors disconnect without warning
After
kMaxErrorCount = 10errors, the client is killed with no notification. The client cannot distinguish between a server crash and an intentional disconnect.4. Global subscription limit kicks clients without notification
When
max_subsis reached, clients are disconnected without any explanation.Suggested behavior
In all four cases, the client should receive a JSON-RPC error response before being disconnected, rather than seeing silent empty data or a raw TCP reset.
1.
max_historyshould return an error instead of empty results{"jsonrpc": "2.0", "error": {"code": 4, "message": "History too large (limit: 125000)"}, "id": 1}2.
max_clients_per_ipshould send an error before closing the connectionRather than an immediate TCP abort, briefly accept the connection and send:
{"jsonrpc": "2.0", "error": {"code": 4, "message": "Connection limit exceeded (12 per IP)"}, "id": null}A hard abort could still apply at some higher threshold (e.g. 2x the limit) to prevent resource exhaustion.
3. Excessive errors should notify before disconnect
{"jsonrpc": "2.0", "error": {"code": 3, "message": "Too many errors, disconnecting"}, "id": null}4. Subscription limit should notify before kick
{"jsonrpc": "2.0", "error": {"code": 4, "message": "Subscription limit reached, disconnecting"}, "id": null}