Troubleshooting
Common problems when verifying and decoding DataLink reports, and how to fix them.
Error reference
| Error | Selector | Raised by | Typical cause |
|---|---|---|---|
VerifierNotFound(bytes32) | 0xb151802b | VerifierProxy | Malformed payload, or wrong network |
BadVerification() | 0x4df18f07 | Verifier | Payload changed after signing, or signatures don't match |
IncorrectSignatureCount(uint256,uint256) | 0x5348a282 | Verifier | Signatures removed or added |
AccessForbidden() | 0xef67f5d8 | VerifierProxy / Verifier | Caller not allowed by an access controller |
FeeManagerInvalid() | 0x82389419 | VerifierProxy | FeeManager configuration problem |
DigestInactive(bytes32,bytes32) | 0xfc10a283 | Verifier | Report signed under a configuration that has been deactivated |
InactiveFeed(bytes32) | 0x36dbe748 | Verifier | The 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
verifyfrom your own contract and decode the result (see Solidity consumer example). - To check a report off-chain, simulate
verifywith aneth_call(no transaction) and decode the returned bytes, or decode the payload directly (see Signed report verification).
