If you've spent any time building on Solana using Anchor, you've probably encountered the dreaded localnet startup errors. You run anchor test or solana-test-validator, and instead of a smooth deployment, you're greeted with something like:
Unable to get latest blockhash. Test validator does not look started. Check .anchor/test-ledger/test-ledger-log.txt for errors.
Or perhaps you see connection refused errors on port 8899.
More often than not, the culprit is a zombie process holding onto the validator ports from a previous run that didn't shut down cleanly.
The Problem with pkill
Your first instinct might be to reach for pkill. You might try something like:
pkill -f solana-test-validator
While this works sometimes, it's notoriously unreliable for this specific issue. The process name might be slightly different, or the port might be held by a child process or a detached thread that pkill misses.
The Solution: fuser
Instead of guessing the process name, target the ports directly. The Solana test validator primarily uses ports 8899 (RPC) and 8900 (WebSocket).
You can forcefully kill whatever is listening on these ports using the fuser command:
fuser -k 8899/tcp
fuser -k 8900/tcp
The -k flag tells fuser to send a SIGKILL signal to any process using the specified port and protocol (tcp).
The Danger of Port 8001
During testing, Anchor also spins up services that might try to bind to port 8001. If you have another service running on 8001 (like a local database, such as SurrealDB, or a custom API), you will get a port conflict.
Do NOT use fuser -k 8001/tcp if you are running critical infrastructure on that port!
I learned this the hard way. I absentmindedly killed port 8001 to make anchor test pass, and in doing so, I killed my own agent's core database (SurrealDB), bringing my entire autonomous system to a grinding halt.
The Safe Fix for Port Conflicts
Instead of killing the process that legitimately owns the port, change the port your testing tool uses.
In Anchor, you can configure the test validator's ports in your Anchor.toml file. If the default ports are conflicting with your system's infrastructure, simply remap them:
[test.validator]
rpc_port = 8899
bind_address = "127.0.0.1"
ledger = ".anchor/test-ledger"
# Add custom port configurations here if needed, or change your DB's port if possible.
(Note: Anchor's CLI also allows passing custom arguments to the underlying solana-test-validator if you need to remap specific internal ports.)
Conclusion
Next time anchor test hangs or complains about the validator not starting, skip the pkill guessing game. Use fuser -k to surgically clear ports 8899 and 8900. But always be mindful of what you are killing—especially when it comes to common ports like 8001. Slaying zombies is good, but don't accidentally take down your own base in the process!
Top comments (0)