Documentation

Troubleshooting

Common problems when verifying and decoding DataLink reports, and how to fix them.

Error reference

ErrorSelectorRaised byTypical cause
VerifierNotFound(bytes32)0xb151802bVerifierProxyMalformed payload, or wrong network
BadVerification()0x4df18f07VerifierPayload changed after signing, or signatures don't match
IncorrectSignatureCount(uint256,uint256)0x5348a282VerifierSignatures removed or added
AccessForbidden()0xef67f5d8VerifierProxy / VerifierCaller not allowed by an access controller
FeeManagerInvalid()0x82389419VerifierProxyFeeManager configuration problem
DigestInactive(bytes32,bytes32)0xfc10a283VerifierReport signed under a configuration that has been deactivated
InactiveFeed(bytes32)0x36dbe748VerifierThe feed has been deactivated on the Verifier

Invalid or missing 0x prefix

Symptom: your tool rejects the argument ("invalid bytes", "invalid hex", "odd length"), or Remix won't accept the input.

Cause: the API returns payload (and feedId) without 0x; Solidity bytes arguments need it.

Fix: prefix once — 0x + payload. Don't add it twice (0x0x…), and don't add spaces or quotes inside the value.

Malformed signed payload

Symptom: verify reverts with VerifierNotFound (0xb151802b).

Cause: the VerifierProxy reads the first 32 bytes of the payload as the configuration digest. A truncated, re-encoded or otherwise wrong payload yields a digest no Verifier is registered for. For example, passing 0x1234 reverts with VerifierNotFound(0x1234000…).

Fix: use the payload from /api/v1/reports/latest exactly as returned (plus 0x). Don't pass the decoded JSON, the feedId, or a hand-built value.

VerifierNotFound

Besides a malformed payload, also check that you are calling the VerifierProxy on XDC Mainnet (chain ID 50): 0xCf49c434f2206Df1D507dE9f5DA70cA8c3dA61d2. Calling another network, or another contract, won't find the Verifier. (Verification isn't available on XDC Apothem Testnet yet.)

BadVerification

Symptom: verify reverts with BadVerification (0x4df18f07).

Cause: the signatures don't match the report — any changed byte in the report data or in a signature causes this.

Fix: fetch a fresh report and pass it unchanged. Make sure nothing in your pipeline modifies it (string trimming, re-encoding, JSON number conversion).

AccessForbidden

Symptom: verify reverts with AccessForbidden (0xef67f5d8).

Cause: an access controller restricts who may verify. No access controller is configured on XDC Mainnet today, so this shouldn't occur there. If it does, the configuration has changed — contact the Marketplace team.

FeeManager errors

XDC Mainnet has no FeeManager configured: verification is free and parameterPayload is ignored (pass 0x). FeeManager errors such as FeeManagerInvalid shouldn't occur today.

If fees are introduced in the future, parameterPayload would need to carry fee information and a payment or token approval might be required. Those details are not available for the current deployment and are deliberately not documented yet.

Wrong feed ID

Symptom: your contract rejects the report (in the example contract: WrongFeed), or you get another asset's price.

Cause: a report is validly signed for its own feed. Verification succeeds for any feed — it's up to your contract to check which one.

Fix: request the report with the right feedID, and always compare report.feedId with the feed your contract expects. Feed IDs are 32 bytes; compare them as bytes32 (the API returns them without 0x).

Incorrect decimals

Symptom: prices are off by a power of ten.

Cause: prices are integers with a per-feed number of decimals.

Fix: read the feed's decimals from the decoded API (schema.fields[].decimals) or its Feed Access page; don't assume a default. With 8 decimals, 8157000000 is 81.57. Don't use floating point for exact values — see Report schema.

Stale reports

Symptom: your contract rejects a report as stale (in the example: StaleReport), or a contract without a freshness check accepts an old price.

Cause: a signed report never expires — an old report still verifies.

Fix: fetch a new report just before sending the transaction, and check freshness on-chain using observationsTimestamp against block.timestamp. Don't use the API's createdAt: it isn't part of the signed data. Also reject reports that are not newer than the one you already stored.

Empty decoded transaction output

Symptom: the explorer shows the verification transaction succeeded, but no decoded output or report values.

Cause: the report values are the return value of verify. Return values of transactions are not stored on-chain, so explorers can't display them. The ReportVerified event only contains the feedId and the requester. If the explorer has no verified source for the contract, it may not decode the input or the event either.

Fix:

  • To use the values on-chain, call verify from your own contract and decode the result (see Solidity consumer example).
  • To check a report off-chain, simulate verify with an eth_call (no transaction) and decode the returned bytes, or decode the payload directly (see Signed report verification).