How to Fix MetaMask Chain ID Errors
In this tutorial, you'll learn about How to Fix MetaMask Chain ID Errors. We cover key concepts, practical examples, and best practices.
The Problem
Your dApp shows MetaMask: Invalid chain ID or The endpoint returned a different chain ID than the one configured. The network dropdown shows the wrong network, and transactions fail because they are sent to the wrong chain. Chain ID mismatches can cause lost funds.
Quick Fix
Fix 1: MetaMask on the Wrong Network
WRONG — deploying to Sepolia but MetaMask is on Ethereum mainnet:
# (transaction hangs or shows "network does not match")
RIGHT — programmatically switch the network:
// ethers.js v6:
async function ensureCorrectNetwork() {
if (!window.ethereum) return;
const provider = new ethers.BrowserProvider(window.ethereum);
const network = await provider.getNetwork();
const targetChainId = 11155111n; // Sepolia
if (network.chainId !== targetChainId) {
try {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: "0xaa36a7" }], // Sepolia chain ID in hex
});
} catch (error) {
if (error.code === 4902) {
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [{
chainId: "0xaa36a7",
chainName: "Sepolia Testnet",
rpcUrls: ["https://sepolia.infura.io/v3/YOUR_KEY"],
nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
}],
});
}
}
}
}
Fix 2: Wrong Chain ID in Hex Format
WRONG — decimal instead of hex:
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: 11155111 }], // WRONG — must be hex string
});
// MetaMask: Invalid chain ID (number)
RIGHT — use hex string format:
// Convert to hex:
const chainIdHex = "0x" + (11155111).toString(16);
console.log(chainIdHex);
// "0xaa36a7"
// Use directly:
params: [{ chainId: "0xaa36a7" }]
Fix 3: RPC Returns Wrong Chain ID
// MetaMask shows: "The endpoint returned a different chain ID"
// (the configured RPC URL returns a different chain than expected)
RIGHT — verify RPC endpoint chain ID:
curl -X POST https://sepolia.infura.io/v3/YOUR_KEY \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
# {"jsonrpc":"2.0","id":1,"result":"0xaa36a7"}
# (should match 11155111 decimal)
Fix 4: Custom Network Configuration
WRONG — guessing the chain ID:
// User manually adds a network but enters wrong chain ID:
// Chain ID: 1 (Ethereum mainnet) — but RPC URL points to Sepolia
// (transactions fail: "nonce too low" or sender doesn't have enough funds)
RIGHT — use wallet_addEthereumChain for precise configuration:
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [{
chainId: "0xaa36a7",
chainName: "Sepolia Testnet",
rpcUrls: ["https://rpc.sepolia.org"],
nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
blockExplorerUrls: ["https://sepolia.etherscan.io"],
}],
});
Fix 5: Chain ID Mismatch in Hardhat
// hardhat.config.js:
module.exports = {
networks: {
sepolia: {
url: "https://sepolia.infura.io/v3/YOUR_KEY",
chainId: 11155111, // must match the actual chain ID
accounts: [PRIVATE_KEY],
},
},
};
Fix 6: Common Chain ID Reference
| Network | Chain ID | Hex |
|---|---|---|
| Ethereum Mainnet | 1 | 0x1 |
| Sepolia | 11155111 | 0xaa36a7 |
| Goerli | 5 | 0x5 |
| Polygon | 137 | 0x89 |
| BNB Smart Chain | 56 | 0x38 |
| Avalanche C-Chain | 43114 | 0xa86a |
| Arbitrum One | 42161 | 0xa4b1 |
| Optimism | 10 | 0xa |
Use DodaTech's Chain Manager to configure, switch, and verify network connections in your dApp, preventing chain ID mismatches.
Prevention
- Always use hex string format for chain IDs in MetaMask RPC.
- Verify RPC endpoint returns the expected chain ID.
- Handle chain switching failure (code 4902) gracefully.
- Test network switching on multiple wallets.
- Display the connected network name in the dApp UI.
Common Mistakes with chain id
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
These mistakes appear frequently in real-world METAMASK code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro