DEV Community

Isaac Atunbi
Isaac Atunbi

Posted on • Edited on

Redbelly Network Troubleshooting: 18 Practical Fixes for Developers

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}'
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

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}'
Enter fullscreen mode Exit fullscreen mode

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"]
  }]
});
Enter fullscreen mode Exit fullscreen mode

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" }]
  });
}
Enter fullscreen mode Exit fullscreen mode

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

  1. Confirm the wallet address and active environment.
  2. Open Redbelly Access with that wallet.
  3. Complete the credential and account-enablement flow.
  4. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
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());
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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}"
Enter fullscreen mode Exit fullscreen mode

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

  1. Switch the wallet to Redbelly Testnet (153).
  2. Complete Testnet access at https://access.redbelly.network/.
  3. Open https://redbelly.faucetme.pro/ and authenticate with Discord.
  4. Claim to the same address, then verify directly:
cast balance "$ADDRESS" --rpc-url https://governors.testnet.redbelly.network
Enter fullscreen mode Exit fullscreen mode

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 } }
  }
};
Enter fullscreen mode Exit fullscreen mode

Foundry:

[profile.default]
solc_version = "0.8.30"
evm_version = "prague"
Enter fullscreen mode Exit fullscreen mode

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"
    }
  }]
}
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"]
}));
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Then check server logs in that order:

  1. /auth-request created and stored the session.
  2. /callback received the wallet token for the same session ID.
  3. The verifier loaded its Iden3 keys.
  4. DID network registration and state resolver both use chain 153 for Testnet.
  5. allowedIssuers contains 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)