geth --sepolia never finishes syncing post-Merge: run a consensus client with checkpoint sync, then point Hardhat at it
Symptom: geth --sepolia --syncmode full --http ... is started to escape Alchemy/Infura rate limits, and it never reaches a usable head — RPC queries fail or return stale/empty state indefinitely.
Cause: since the Merge, an execution client does not choose the chain head. It only advances when a consensus (beacon) client drives it over the Engine API on the authrpc port, authenticated with a shared JWT secret. Without a CL attached, geth has nothing telling it which fork to follow, so it sits there. Yes, eth_* JSON-RPC is served by the execution client — but the execution client cannot be synced without a CL, so both are required even for a pure RPC endpoint.
Setup that works:
1. Run geth with --authrpc.jwtsecret=/path/jwt.hex --http --http.api eth,net,web3.
2. Run a beacon client (lighthouse / prysm / teku / nimbus) for the same network, with the same --jwt-secrets/--authrpc.jwtsecret file and an execution endpoint of http://localhost:8551.
3. Give the beacon client --checkpoint-sync-url from the public checkpoint list (eth-clients.github.io/checkpoint-sync-endpoints); this brings the pair up in hours instead of days.
4. Point tooling at your node — no API key involved:
networks: { sepolia: { url: 'http://127.0.0.1:8545', accounts: [PRIVATE_KEY] } }Locally you can also skip HTTP entirely and use the IPC socket (~/.ethereum/sepolia/geth.ipc), including geth attach ~/.ethereum/sepolia/geth.ipc for a JS console.
Expectations: rate limits disappear, but you own the disk and bandwidth. Sepolia is modest; mainnet archive is not. Also note --syncmode full is unnecessary for development — snap sync plus a checkpoint gives a fully validating node much faster, and only historical-state queries need an archive node.
Source: adapted from a Stack Exchange answer by Maka (question by ayman), https://ethereum.stackexchange.com/questions/162187/full-node-on-sepolia — CC BY-SA 4.0