Use this guide when an RPC call, wallet, transaction, deployment, explorer verification, or
Eligibility SDK flow fails on Redbelly. Commands use Testnet unless marked otherwise.
Last technical review: 14 August 2026. Network values are linked to official Redbelly
documentation. Recheck live values before using this guide in production.
Quick reference
| Setting | Mainnet | Testnet |
|---|---|---|
| Chain ID |
151 (0x97) |
153 (0x99) |
| RPC | https://governors.mainnet.redbelly.network |
https://governors.testnet.redbelly.network |
| Explorer | https://redbelly.routescan.io |
https://redbelly.testnet.routescan.io |
| Currency | RBNT |
RBNT |
Source: Redbelly environments. DevNet chain
152 is deprecated.
Find an error
| Error or symptom | Fix |
|---|---|
could not detect network, timeout, ECONNREFUSED
|
1. Check the RPC URL |
HTTP 429 Too Many Requests
|
2. Back off and change request design |
| Chain ID does not match | 3. Pair the correct chain ID and RPC |
| Redbelly absent from MetaMask | 4. Add the network |
| Wallet or explorer shows the wrong network | 5. Switch and verify the active chain |
| Transaction reverts despite a balance | 6. Check write permission |
Gas estimate is null, missing, or reverts |
7. Isolate balance, permission, and contract errors |
insufficient funds for gas * price + value |
8. Fund the sender and use the live gas price |
| Transaction remains pending | 9. Inspect and replace it |
replacement transaction underpriced |
9. Raise the fee on the same nonce |
nonce too low or nonce has already been used
|
10. Refresh the pending nonce |
| Faucet does not send RBNT | 11. Complete access and faucet authentication |
| Contract deploys locally but fails on Redbelly | 12. Compile for Prague |
| Verification network is unsupported | 13. Configure Routescan |
| Verification succeeds but source is absent | 14. Match the build exactly |
SDK install returns 404 or 401
|
15. Configure GitHub Packages |
| Eligibility widget renders nothing | 16. Restore the React provider tree |
| Wallet cannot call a local callback / CORS error | 17. Expose the backend correctly |
| Proof stays pending or fails to verify | 18. Check routes, keys, issuer, and network |
Network and RPC
1. RPC connection fails or times out
Symptom
could not detect network, ETIMEDOUT, ECONNREFUSED, or a JSON parser error appears
before any transaction is sent.
Root Cause
The project is using an old DevNet host, adding an unsupported /rpc suffix, or treating an
HTML proxy response as JSON. The current public endpoint accepts JSON-RPC at the domain root.
Solution
Test the endpoint independently:
curl -sS -X POST https://governors.testnet.redbelly.network \
-H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
The result should be 0x99. Use the same URL, without /rpc, in your application.
Prevention
Store the RPC URL once in an environment variable and add an eth_chainId startup check.
2. RPC returns HTTP 429
Symptom
The RPC responds with 429 Too Many Requests, often during polling, indexing, or a burst of
parallel calls.
Root Cause
The client exceeded a gateway limit. Redbelly does not publish a fixed public threshold, and
a previous 40-request burst did not reproduce a 429, so do not encode a guessed limit.
Solution
Respect Retry-After when present and retry idempotent reads with capped exponential backoff:
async function rpcWithBackoff(call, attempts = 5) {
for (let i = 0; i < attempts; i++) {
const response = await call();
if (response.status !== 429) return response;
const retryAfter = Number(response.headers.get("retry-after"));
const delay = Number.isFinite(retryAfter) ? retryAfter * 1000 : 500 * 2 ** i;
await new Promise((resolve) => setTimeout(resolve, Math.min(delay, 8000)));
}
throw new Error("RPC remained rate-limited after 5 attempts");
}
Reduce duplicate polling and limit concurrency before changing endpoints.
Prevention
Cache immutable reads, batch where supported, and avoid one polling timer per UI component.
3. Chain ID returned does not match
Symptom
MetaMask reports that the chain ID returned by the custom network does not match the chain ID
entered, or a library raises network changed.
Root Cause
The chain ID and RPC belong to different environments, or an old document supplied chain
152 or 154. Current public environments are mainnet 151 and testnet 153.
Solution
Ask the endpoint instead of guessing:
curl -sS -X POST "$RPC_URL" -H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
Use 0x97/151 with the mainnet RPC and 0x99/153 with the testnet RPC.
Prevention
Define each environment as one object containing its RPC URL, chain ID, and explorer URL.
Wallet and permissioning
4. MetaMask does not show Redbelly
Symptom
Searching MetaMask's default network list does not find Redbelly.
Root Cause
A compatible EVM network can work without being preloaded in every wallet. It must be added
as a custom network.
Solution
In MetaMask, open Networks → Add a custom network and enter the Testnet values from the
quick-reference table. A dapp can request the same configuration:
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [{
chainId: "0x99",
chainName: "Redbelly Testnet",
nativeCurrency: { name: "RBNT", symbol: "RBNT", decimals: 18 },
rpcUrls: ["https://governors.testnet.redbelly.network"],
blockExplorerUrls: ["https://redbelly.testnet.routescan.io"]
}]
});
Prevention
Offer an “Add Redbelly Testnet” button and keep its values in the same chain configuration
used by your RPC client.
5. Wallet is connected to the wrong Redbelly network
Symptom
A known contract has no code, a balance appears missing, or the explorer cannot find a
transaction that the wallet shows.
Root Cause
The wallet, RPC client, contract address, and explorer are not all using the same chain.
Solution
Read the wallet chain before enabling a transaction button:
const chainId = await window.ethereum.request({ method: "eth_chainId" });
if (chainId !== "0x99") {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: "0x99" }]
});
}
Then search the transaction on the Testnet explorer, not the mainnet explorer.
Prevention
Show the active chain name beside every write action and reject unsupported chain IDs.
6. Account can receive RBNT but cannot send
Symptom
The account has RBNT, but a send or contract call reverts without a useful reason. A simple
gas estimate may still succeed.
Root Cause
Redbelly requires an access credential before an account receives write access. Receiving
funds does not prove that the account may send transactions.
Solution
- Confirm the wallet address and active environment.
- Open Redbelly Access with that wallet.
- Complete the credential and account-enablement flow.
- Reconnect the wallet, then retry a small Testnet transaction.
Do not paste a private key into a support chat or access form.
Prevention
Make network access an explicit onboarding prerequisite. For SDK applications, use the
documented useHasChainPermission hook before offering a write action.
Source: Redbelly user access.
Gas and transactions
7. Gas estimation fails
Symptom
eth_estimateGas returns an error, the SDK reports a missing estimate, or ethers reports
CALL_EXCEPTION before sending.
Root Cause
Estimation executes the call without mining it. It fails when the sender cannot fund the
transaction, the target is wrong, calldata triggers a contract revert, or the account lacks
the required setup. A self-transfer estimate alone does not prove write permission.
Solution
Check the inputs separately:
# Balance
cast balance "$ADDRESS" --rpc-url https://governors.testnet.redbelly.network
# Code at the target; 0x means no contract exists there
cast code "$CONTRACT" --rpc-url https://governors.testnet.redbelly.network
# Exact call, including sender
cast estimate "$CONTRACT" "methodName(uint256)" 1 \
--from "$ADDRESS" --rpc-url https://governors.testnet.redbelly.network
Decode a contract revert before increasing the gas limit. Extra gas cannot fix a failed
requirement.
Prevention
Run contract tests for revert conditions and validate chain ID, target address, balance, and
permission before estimating.
8. Hardhat reports insufficient funds
Symptom
insufficient funds for gas * price + value appears during deployment.
Root Cause
The signer lacks enough Testnet RBNT for gasLimit × live gasPrice + value, is funded on a
different chain, or the project hardcoded an Ethereum-style gas price. Redbelly fees are
stabilized in US-dollar terms, so the RBNT-denominated gas price changes.
Solution
npx hardhat console --network redbellyTestnet
const [signer] = await ethers.getSigners();
const address = await signer.getAddress();
console.log(address);
console.log(ethers.formatEther(await ethers.provider.getBalance(address)));
console.log(await ethers.provider.getFeeData());
Fund that exact address, remove hardcoded gasPrice/maxFeePerGas, and retry only after the
balance is visible on chain.
Prevention
Print network, signer, balance, estimated gas, and fee data at the start of deployment.
Source: Redbelly network fees.
9. Transaction remains pending
Symptom
A transaction hash exists but does not confirm, or replacement attempts return
replacement transaction underpriced.
Root Cause
The original transaction may use a stale, hardcoded gas price. A replacement must use the
same nonce and a fee high enough for the node to prefer it.
Solution
Check the transaction and current gas price:
cast tx "$TX_HASH" --rpc-url https://governors.testnet.redbelly.network
cast gas-price --rpc-url https://governors.testnet.redbelly.network
If the original is still pending, send a replacement with the same nonce and the current
network fee plus a reasonable bump. With ethers:
const fee = await provider.getFeeData();
if (fee.gasPrice == null) throw new Error("Provider did not return a legacy gas price");
const replacement = await wallet.sendTransaction({
to: wallet.address,
value: 0n,
nonce: stuckNonce,
gasPrice: fee.gasPrice * 120n / 100n
});
await replacement.wait();
Confirm your provider returns gasPrice before using this legacy-fee example.
Prevention
Do not hardcode fees. Wait for a transaction receipt before reusing its nonce.
10. Nonce too low
Symptom
nonce too low, nonce has already been used, or invalid nonce; expected N.
Root Cause
The nonce was already mined or reserved by another pending transaction, often because two
tools are sending from the same account.
Solution
Compare confirmed and pending counts:
RPC=https://governors.testnet.redbelly.network
curl -sS -X POST "$RPC" -H 'content-type: application/json' \
--data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"$ADDRESS\",\"latest\"],\"id\":1}"
curl -sS -X POST "$RPC" -H 'content-type: application/json' \
--data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"$ADDRESS\",\"pending\"],\"id\":2}"
For sequential ethers scripts, omit the manual nonce and wait for each receipt. For parallel
sends, wrap the signer in new ethers.NonceManager(wallet) or allocate nonces from one
pending base.
Prevention
Use one sending process per key. Never drive the same deployment account from MetaMask and a
script at the same time.
Testnet funding
11. Testnet faucet does not send RBNT
Symptom
The faucet completes without a visible balance, rejects authentication, or does not allow a
claim.
Root Cause
The official testing-coin flow uses FAUCETME with Discord authentication. The wallet may
also be viewing the wrong chain, or the address may not have completed network access.
Solution
- Switch the wallet to Redbelly Testnet (
153). - Complete Testnet access at https://access.redbelly.network/.
- Open https://redbelly.faucetme.pro/ and authenticate with Discord.
- Claim to the same address, then verify directly:
cast balance "$ADDRESS" --rpc-url https://governors.testnet.redbelly.network
If it still fails, keep the address, approximate time, and transaction hash (if any) for a
support request. Never share the private key.
Prevention
Complete wallet, access, and faucet setup before a workshop or deployment session.
Source: Redbelly testing coins.
Deployment and verification
12. Contract bytecode targets the wrong EVM version
Symptom
A contract works in a local VM but deployment fails or execution encounters an unsupported
opcode after a compiler upgrade.
Root Cause
Redbelly documents Prague EVM compatibility and Solidity 0.8.30. Newer Solidity defaults
may target a later EVM unless the target is pinned.
Solution
Pin the compiler and EVM target. Hardhat 3 example:
export default {
solidity: {
version: "0.8.30",
settings: { evmVersion: "prague", optimizer: { enabled: true, runs: 200 } }
}
};
Foundry:
[profile.default]
solc_version = "0.8.30"
evm_version = "prague"
Delete stale artifacts and compile again.
Prevention
Pin both compiler and EVM version in version control; do not rely on compiler defaults.
Source: Redbelly EVM compatibility.
13. Hardhat cannot find a verification service
Symptom
The verification plugin reports that chain 153 is unsupported or has no explorer API.
Root Cause
The plugin does not know Redbelly Testnet automatically. Routescan exposes an
Etherscan-compatible API, but it must be configured for the exact plugin version in use.
Solution
First confirm the target address is on Testnet. For Hardhat 2 with
@nomicfoundation/hardhat-verify, add a custom chain:
etherscan: {
apiKey: { redbellyTestnet: "routescan" },
customChains: [{
network: "redbellyTestnet",
chainId: 153,
urls: {
apiURL: "https://api.routescan.io/v2/network/testnet/evm/153/etherscan/api",
browserURL: "https://redbelly.testnet.routescan.io"
}
}]
}
Then run the plugin command documented for your installed Hardhat major version. Hardhat 3
uses a different configuration shape; do not paste a Hardhat 2 block into it.
Prevention
Pin Hardhat and the verification plugin together, and keep version-specific configs separate.
14. Explorer source verification does not match
Symptom
Verification returns a bytecode mismatch, cannot find the contract, or leaves the contract
page without published source.
Root Cause
The submitted compiler version, EVM target, optimizer settings, source paths, libraries, or
constructor arguments differ from the deployment build.
Solution
Rebuild from the exact deployment commit and inspect its build information:
npx hardhat clean
npx hardhat compile
npx hardhat verify --network redbellyTestnet \
0xYOUR_CONTRACT_ADDRESS "constructor argument"
If libraries were linked, supply the same library addresses. Do not redeploy merely to make
verification easier; preserve and use the original build settings.
Prevention
Commit the lockfile and deployment input, record the git commit and constructor arguments,
and verify immediately after deployment.
Eligibility SDK
15. Eligibility SDK install fails with 404 or 401
Symptom
npm install @redbellynetwork/eligibility-sdk returns 404 Not Found, 401 Unauthorized,
or permission_denied: read_package.
Root Cause
The package is private on GitHub Packages, not the public npm registry. npm needs a GitHub
token with read:packages and the scoped registry line.
Solution
Create .npmrc in the project root:
@redbellynetwork:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
always-auth=true
Export the token in the current shell, install, and remove any token accidentally written to
the file:
export GITHUB_TOKEN='your-token-with-read-packages'
npm install @redbellynetwork/eligibility-sdk
Prevention
Commit only the variable-based .npmrc. Store GITHUB_TOKEN in the deployment platform's
secret manager.
Source: Eligibility SDK installation.
16. Eligibility widget does not render
Symptom
The page loads but the widget is blank, hooks throw a provider error, or Next.js reports
window is not defined.
Root Cause
The SDK is a React component—not an iframe. It depends on React 18+, Wagmi, TanStack Query,
Reown AppKit, and EligibilitySDKProvider. Wallet UI must run in a client component.
Solution
Install peer dependencies:
npm install @reown/appkit @reown/appkit-adapter-wagmi \
wagmi viem @tanstack/react-query
In Next.js, put 'use client'; at the top of the component that initializes AppKit. Wrap the
app in this order:
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<EligibilitySDKProvider config={{ network: "testnet", apiKey }}>
<App />
</EligibilitySDKProvider>
</QueryClientProvider>
</WagmiProvider>
Prevention
Keep wallet and SDK initialization in one client-only provider module and test it after every
dependency upgrade.
Source: Eligibility Widget integration.
17. Wallet callback or CORS fails
Symptom
The QR code opens, but the mobile wallet cannot return proof; browser logs show a CORS error;
or the callback points to localhost.
Root Cause
The wallet is a separate device/process and cannot reach your computer's localhost. The
verifier backend also needs to allow the frontend origin. This is a callback-origin problem,
not an iframe problem.
Solution
Expose local development over HTTPS:
ngrok http 3000
Use the generated HTTPS origin for the callback/base URL. Configure CORS narrowly on the
backend, for example:
app.use(cors({
origin: "https://your-frontend.example",
methods: ["GET", "POST"],
allowedHeaders: ["content-type", "authorization"]
}));
Do not use origin: "*" with credentials.
Prevention
Use environment-specific public base URLs and run one mobile-wallet callback test before
release.
Source: Eligibility SDK quickstart.
18. Eligibility proof never completes
Symptom
The widget remains pending, /status never changes, or proof verification fails after the
wallet submits.
Root Cause
The verifier may be missing a required route, Iden3 verification keys, the Redbelly DID
registration, a correct state resolver, or an authorized issuer DID for the selected network.
Solution
Confirm these routes share the same base URL configured in the SDK:
POST /auth-request
POST /callback
GET /status/:id
Then check server logs in that order:
-
/auth-requestcreated and stored the session. -
/callbackreceived the wallet token for the same session ID. - The verifier loaded its Iden3 keys.
- DID network registration and state resolver both use chain
153for Testnet. -
allowedIssuerscontains the intended Testnet issuer DID rather than an unsafe wildcard.
Keep proof requirements (scope) on the server; never accept them from the browser.
Prevention
Add a health check for routes and keys, log session transitions without credentials, and run
an end-to-end proof on every environment before deployment.
Source: Eligibility SDK backend setup.
When asking for help
Include the chain ID, public address, transaction hash, exact command, package versions, and
complete error text. Remove private keys, seed phrases, access tokens, API keys, and personal
identity data before posting.
Research and verification
The issue-selection method and current community-validation status are recorded in
evidence/channel-analysis.md. Technical source links and
the scope of automated checks are recorded in evidence/sources.md.
The guide does not claim that a failed or unrun check passed.
Top comments (0)