Solana RPC Node Is Behind
Diagnose Solana RPC node lag, slot freshness, health checks, and safe response policy when an endpoint reports that it is behind the cluster tip.
Solana RPC Node Is Behind
Node is behind is a freshness signal. It means an RPC node is answering from a view that is too far behind the cluster tip for the node health threshold.
Do not treat it as a generic provider verdict. The useful first question is narrower: which request path is behind, by how much, at which commitment level, and does this workload need to stop or can it safely degrade?
Part of the Carbium Solana infrastructure stack.
What the error means
Solana's getHealth method reports ok when the node is within its configured slot distance of the cluster tip. When it is not, the RPC response can return a JSON-RPC error such as:
{
"jsonrpc": "2.0",
"error": {
"code": -32005,
"message": "Node is behind by 42 slots",
"data": {
"numSlotsBehind": 42
}
},
"id": 1
}That error is useful, but the exact payload is not a contract you should build your whole incident system around. Use it as a signal, then compare slots and request behavior with your own logs.
Fast triage
| Question | Why it matters | First check |
|---|---|---|
Is only getHealth failing? | Health can fail while some read paths still answer | Run a cheap getSlot at the commitment your app uses |
| Is the slot actually stale? | A reachable endpoint can still be too far behind for trading or confirmation logic | Compare getSlot against your expected fresh source |
| Is the error isolated to one method? | Method-level failures are different from endpoint-wide lag | Check method mix in Calls Monitoring |
| Did traffic spike first? | Retry storms and health probes can worsen incidents | Inspect recent 429, timeout, and retry patterns |
| Are writes involved? | A stale or unclear write path can create duplicate-send risk | Check signature status before retrying sends |
The goal is to separate node freshness from application behavior. A behind signal plus a retry loop is a different incident from a behind signal during normal traffic.
A minimal freshness probe
Use the same commitment level your application depends on. If your app makes live decisions at confirmed, probe confirmed; if it reconciles irreversible state, also inspect finalized.
curl -s "https://rpc.carbium.io/?apiKey=$CARBIUM_RPC_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getSlot",
"params": [
{
"commitment": "confirmed"
}
]
}'If you compare multiple endpoints, log all of these together:
- endpoint name, not the full URL with the API key
- method and commitment level
- returned slot
- request duration
- attempt number
- user-facing workflow affected
Avoid comparing a processed slot from one path to a finalized slot from another and calling the gap a provider failure. Commitment mismatch creates false alarms.
Decide by workload
Wallet and dashboard reads
Balance, portfolio, token, and dashboard reads can often degrade safely if the app labels the answer and avoids presenting stale data as final. The safer response is usually:
- retry once with backoff
- compare slot freshness
- show a temporary stale-data state if needed
- avoid increasing polling frequency during the incident
For a simple balance-read example, use Check a Wallet Balance With Carbium RPC.
Trading and quote support reads
Trading systems should be stricter. A stale pool read, stale blockhash, or stale route assumption can turn a good quote into a bad execution path.
If the slot gap exceeds your policy threshold, rebuild the decision instead of carrying it forward. For the full quote-to-submit shape, use Quote to Swap Integration Guide.
Transaction sends and confirmations
Do not blindly resend because one endpoint looked behind or timed out.
For writes, treat the signature as the source of truth once you have it:
- submit once through the chosen path
- persist the signature immediately
- call
getSignatureStatusesbefore deciding to retry - rebuild and re-sign only when the old transaction is expired or clearly not accepted
If blockhash expiry is involved, use Blockhash Expiry Recovery Playbook.
Common causes to rule out
| Signal | Likely area | What to do |
|---|---|---|
Node is behind by N slots from getHealth | Endpoint freshness | Check getSlot at the same commitment and record the slot gap |
429 around the same window | Rate-limit pressure | Reduce burst traffic before widening retries |
| High health-check volume | Monitoring design | Slow probes and use cheap representative checks |
| Stale read only in one worker | Client routing | Check worker endpoint config and retry policy |
| Send path timeout followed by duplicate attempts | Write retry policy | Query signature status before any second send |
| Blockhash-related errors | Transaction freshness | Rebuild with a fresh blockhash instead of replaying stale bytes |
For full HTTP and JSON-RPC classification, use RPC Errors Reference. For 429 specifically, use Solana RPC Rate Limits Explained.
Production policy
The policy should be boring and explicit:
- define the maximum slot gap each workload can tolerate
- probe with the same commitment level used by the workload
- keep health checks cheap and rate-limited
- add jitter to retries so workers do not restart into the same second
- label fallback reads with endpoint and slot context
- stop high-risk execution paths when freshness is below policy
- check known signatures before resending transactions
- redact API keys from incident logs and screenshots
If you use multiple RPC paths, read Safe RPC Failover Checklist before enabling automatic failover.
Escalation payload
When you need support, include enough detail to separate provider health from client traffic:
| Include | Example |
|---|---|
| Time window | 2026-06-02 08:00-08:10 UTC |
| Product surface | Carbium RPC |
| Method and commitment | getSlot, confirmed |
| Returned error | Node is behind by 42 slots, if present |
| Returned slot | slot number from the probe |
| Traffic change | deploy, batch job, bot restart, user spike |
| Retry behavior | max attempts, backoff, jitter, queue state |
| Impact | reads stale, writes paused, confirmations delayed |
Do not include full authenticated endpoint URLs, private keys, wallet seed phrases, or raw secrets in support payloads.
Node is behindis a reason to measure freshness and protect the workload. It is not a reason to multiply retries, bypass confirmation checks, or send the same transaction again without knowing what happened to the first attempt.
Source checks
- Solana
getHealthdocuments the healthy vs unhealthy behavior and theNode is behind by N slotsexample. - Solana
getSlotreturns the highest slot reached at the requested commitment. - Solana
getLatestBlockhashreturns both the blockhash andlastValidBlockHeight. - Solana
getSignatureStatusesis the confirmation check to use before retrying unclear transaction sends.
