HH108 'Cannot connect to the network' when Hardhat Network forks mainnet after pinning an old blockNumber
0 reputation · 12 Jan 2020, 08:17 UTC
0 reputation · 12 Jan 2020, 08:17 UTC
I am setting up local mainnet forking with the Hardhat Network using the networks.hardhat.forking config, with a url and a blockNumber pinned for reproducibility. Intermittently, startup fails with the documented connection error HH108 ("Cannot connect to the network"), and I cannot tell whether the failure is the endpoint being unreachable, the pinned block being older than what the node retains, or stale fork cache from an earlier run.
My constraints: the upstream endpoint may be a non-archive node, the pinned block is several months old, and tests are also run unpinned in CI, where results drift as the upstream chain advances. I have seen references to hardhat_reset as a way to re-initialize the fork at runtime, but its interaction with the local cache and an unreachable endpoint is unclear to me.
How can I distinguish, from the HH108 failure alone, between a connectivity problem and a request for state the upstream node no longer serves? Does hardhat_reset clear the cached fork state, or must the cache be invalidated separately? Is pinning a blockNumber the recommended way to get deterministic fork behavior across runs?
35275 reputation · 12 Jan 2020, 10:22 UTC
The HH108 error is a generic “cannot complete the initial JSON‑RPC handshake” failure. It does not distinguish between a network outage and a non‑archive node that no longer stores the requested block. To know which one is happening, you must query the endpoint directly.
Run a raw JSON‑RPC request against the same URL you configured in networks.hardhat.forking:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["0x{blockNumber}",false]}' \
http://YOUR_ENDPOINT
Replace {blockNumber} with the hex value you pinned. Interpret the result:
hardhat_resethardhat_reset is a Hardhat‑specific JSON‑RPC method that re‑initialises the in‑memory fork state (accounts, pending txs, snapshots). It does not delete the on‑disk fork cache that Hardhat keeps under ./.hardhat/cache (or the platform‑specific cache directory). Changing the fork configuration (URL or blockNumber) automatically invalidates the relevant cache key, but if you suspect corruption you should delete the cache folder manually:
rm -rf .hardhat/cache
After clearing the cache, the next hardhat_reset will fetch fresh state from the upstream node.
Pinning a block number is the recommended way to get deterministic forks across runs. Without a pin, each Hardhat session forks from the latest block and test results drift as the chain advances, which is problematic in CI pipelines. However, pinning works only if the upstream endpoint can serve that historical state—i.e., it must be an archive node. If you must fork from a months‑old block, use a provider that offers archive access (e.g., Alchemy, Infura archive tier). Otherwise, the fork will fail with HH108 or return null for the block, as you’ve observed.
To refine the recommendation, it would help to know: Which RPC provider and tier are you using for the url? If it’s a free tier that keeps only the last few weeks, that explains the failure. If it’s an archive tier, a different issue (e.g., cache corruption) is likely.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.