Health & IBD
Server Health and Initial Block Download Reference
blockd exposes server health through two interfaces:
WebSocket — subscribe to server.health for real-time push events at a configurable
interval. This is the preferred method for applications that need continuous health
monitoring without polling. See Health Events.
REST — poll GET /health on demand. Available before blockd reaches ready state,
making it suitable for readiness probes and one-off checks. See
REST Version & Health.
Both interfaces return the same data. This page is the complete field reference for both.
Health response
Section titled “Health response”Base fields (always present):
{ "time": 1771612931, "up_since": 1771612819, "state": "ready", "ready_at": 1771612824, "tracking_since": 1771612824}With tip:
{ "tip": { "time": 1771612349, "height": 292411, "hash": "00000000590f69588b42f409796be4049ad8c4528e04f26f2fdabebbab7e0e18" }}With detailed:
{ "core": { "state": "synced", "connected_at": 1771612823, "polled_at": 1771613117, "rpc_errors": 0, "zmq_outages": 0 }, "indexer": { "state": "synced", "connected_at": 1771612823, "polled_at": 1771613064, "disconnects": 0, "degradations": 0, "errors": 0, "tracking_since": 1771612824 }}core fields:
| Field | Description |
|---|---|
state | See bitcoind states above |
connected_at | Unix timestamp when blockd connected to bitcoind |
polled_at | Unix timestamp of the most recent RPC poll |
rpc_errors | RPC error count since blockd started |
zmq_outages | See ZMQ monitoring below |
zmq_outage_at | See ZMQ monitoring below |
indexer fields:
| Field | Description |
|---|---|
state | See indexer states above |
connected_at | Unix timestamp when blockd connected to the indexer |
polled_at | Unix timestamp of the most recent indexer poll |
disconnects | Disconnection count since blockd started |
degradations | Degradation event count since blockd started |
errors | Error count since blockd started |
tracking_since | See Cache invalidation below |
tracking_since is mirrored as a top-level base field for convenience — callers that only
need this value don’t have to request the detailed level. Both fields always carry the same value.
During IBD, ibd is present:
{ "ibd": { "blocks_synced": 450000, "blocks_total": 892411, "per_sec_5min": 142.3, "per_sec_total": 98.7, "est_progress": 0.5039 }}All timestamps are Unix seconds.
Optional fields:
| Field | Present when |
|---|---|
ready_at | Server has reached ready state |
tracking_since | Indexer is synced with bitcoind — see Cache invalidation |
tip | Requested via REST level or WebSocket subscription arg |
ibd | bitcoind is in initial block download |
core | Requested via REST detailed level or WebSocket subscription arg |
indexer | Requested via REST detailed level or WebSocket subscription arg |
States
Section titled “States”Server state:
| State | Description |
|---|---|
offline | bitcoind or Fulcrum is unreachable |
ibd | bitcoind is in initial block download |
syncing | bitcoind is syncing after IBD |
ready | All services synced and ready to serve requests |
degraded | One or more services are experiencing errors |
bitcoind state (core.state):
| State | Description |
|---|---|
offline | bitcoind is unreachable |
ibd | Initial block download in progress |
syncing | Catching up to chain tip |
synced | At chain tip and healthy |
degraded | Reachable but experiencing RPC or ZMQ errors |
Indexer state (indexer.state):
| State | Description |
|---|---|
disconnected | Fulcrum is unreachable |
connected | Connected but not yet synced |
syncing | Building or catching up its index |
synced | At chain tip and healthy |
degraded | Connected but experiencing errors |
Fields
Section titled “Fields”message:
| Field | Type | Present when |
|---|---|---|
core.message | string | A fault or warning condition exists on bitcoind |
indexer.message | string | A fault or warning condition exists on the indexer |
Omitted entirely under normal operating conditions. When present, suitable for display in application UIs.
Example core messages:
"RPC error: down""catching up - 12 blocks remaining""no peer connections""slow - no block for 56 minutes but healthy. mempool: 1034 peers: 21""warning - no block for 45 minutes. mempool: 1231 peers: 16""critical - no block for 65 minutes. mempool: 0 peers: 0"Example indexer messages:
"indexer is more than one block behind"Cache invalidation
Section titled “Cache invalidation”If tracking_since changes from a previously observed value, all cached workflow results
are stale — re-submit workflows and re-fetch transactions and UTXOs for all tracked
pubkeys sets.
ZMQ monitoring
Section titled “ZMQ monitoring”blockd monitors all ZMQ connections to bitcoind using socket-level monitoring. Most Bitcoin node integrations do not monitor ZMQ at this depth — blockd exposes this information so applications can make informed decisions about node stability.
| Field | Description |
|---|---|
zmq_outages | Number of ZMQ disruptions since blockd started |
zmq_outage_at | Unix timestamp of the most recent ZMQ outage. Absent if none have occurred |
A value of 0 for zmq_outages means a ZMQ connection has been stable throughout.
Values greater than 0 indicate disruptions occurred — ZMQ reconnects automatically,
but non-zero counts suggest the node may have experienced instability. ZMQ outages do
not affect the server state field, which may still read ready during or after a
disruption.
IBD fields
Section titled “IBD fields”Present only when state is ibd. Absent entirely during normal operation.
| Field | Type | Description |
|---|---|---|
blocks_synced | integer | Current block height received |
blocks_total | integer | Total blocks expected (chain tip height) |
per_sec_5min | float | Blocks per second over the most recent 5 minutes. Absent until enough data has been gathered |
per_sec_total | float | Blocks per second over the entire IBD. Absent until enough data has been gathered |
est_progress | float | Estimated sync progress — see below |
message | string | Present only when a stall condition is detected — see below |
est_progress
Section titled “est_progress”A float sourced from bitcoind’s getblockchaininfo verificationprogress field,
rounded by blockd.
bitcoind estimates sync progress as the ratio of transactions processed so far to a projected total transaction count. The projected total is calculated from a hardcoded checkpoint (transaction count + timestamp, updated each Bitcoin Core release) extrapolated forward using an assumed transaction rate. This gives a more meaningful picture of sync progress than block height alone, since early blocks contain very few transactions.
The value will typically reach 0.9999 or above when the node is nearly or fully synced,
and may slightly exceed 1.0 if the actual transaction rate has outpaced the estimate
baked into the running Bitcoin Core version.
Regtest:
est_progressis always reported as1on regtest networks, as no transaction rate statistics are defined for that network type.
IBD message
Section titled “IBD message”Present only when a stall condition is detected. Suitable for display in application UIs.
| Message | Condition |
|---|---|
"stalled - network disabled" | Network connectivity is disabled |
"stalled - no peers" | No peer connections |
"stalled - 0 peers connected" | Peer count is zero |
"stalled - validation backlog 112 blocks behind" | Validation more than 100 blocks behind |
"stalled - slow validation 5 blocks behind" | Validation more than 10 blocks behind |
"stalled - unknown" | Stall detected but cause cannot be diagnosed |
The block count in validation backlog and slow validation messages reflects the current lag at the time of the event.