Errors
Cmd+F for your error number. The row tells you what’s happening and where to look.
Error codes
Section titled “Error codes”Fired by verify
Section titled “Fired by verify”| Code | Variant | Meaning | Most-likely cause | Fix |
|---|---|---|---|---|
6000 | InvalidSignature | Pairing returned Some(false) — equation didn’t hold | Signature doesn’t match drand evmnet for this round. Most common cause: feeding a signature from a different drand chain (mainnet BLS12-381, fastnet, quicknet). | Use fetchBeacon() (SDK default is evmnet) or pass the evmnet chain hash explicitly |
6001 | InvalidG1Point | Signature bytes fail the on-curve check (y² != x³ + 3 mod p) or x ≥ p | Wrong encoding — 48-byte compressed G1, 96-byte G2, or x above field prime | Signature must be 64 bytes, uncompressed (x || y) big-endian. Drand’s REST API returns this shape; the SDK parses it correctly. |
6002 | RoundZero | Round number is 0 | Integer default or off-by-one bug in the caller | Drand rounds start at 1. Use getCurrentRound() or pass an explicit bigint ≥ 1. |
6004 | NoSquareRoot | SVDW hash-to-curve: all 3 candidate field elements fail the square-root check | Should not occur for honest drand input — SVDW theorem guarantees one candidate succeeds. Indicates constant corruption or syscall-oracle regression. | File an issue. Do not retry. |
6006 | PairingError | alt_bn128_pairing syscall returned Err, or output length was wrong | Malformed pairing inputs. Should not occur with valid drand beacons and a correct Config. | File an issue with the round number and full transaction log. |
Fired by initialize / update_config only
Section titled “Fired by initialize / update_config only”These never fire during verify. They’re init/update-time guards on the Config PDA.
| Code | Variant | Meaning |
|---|---|---|
6007 | WrongChainHash | chain_hash argument doesn’t match EXPECTED_EVMNET_CHAIN_HASH. Rejects wrong-chain deploys at init time. |
6008 | WrongPubkey | pubkey_g2 argument doesn’t match EXPECTED_EVMNET_G2_PUBKEY. Fallback guard from ADR 0027. |
6010 | InvalidGenesisTime | genesis_time doesn’t match EXPECTED_EVMNET_GENESIS_TIME |
6011 | InvalidPeriod | period doesn’t match EXPECTED_EVMNET_PERIOD |
6012 | UnauthorizedInit | The signer calling initialize isn’t the BPFLoaderUpgradeable upgrade_authority. Closes the deploy-to-init front-run window. |
Reserved (unreachable in current code)
Section titled “Reserved (unreachable in current code)”Kept in the enum per ADR 0028’s append-only, never-renumber rule so consumer SDKs stay stable across program versions.
| Code | Variant | Why unreachable |
|---|---|---|
6003 | InvalidFieldElement | Hash-to-field uses from_be_bytes_mod_order, so no range check is ever needed. Reserved for a future canonical-Fq guard if one is added. |
6005 | InvalidG2Point | Fallback G2 validation path (ADR 0027) is strictly stronger than subgroup check for this single-chain deployment. Not reachable with the current pubkey. |
6009 | ReturnDataMissing | Anchor 0.30 Pattern A return-data handling (ADR 0030) always sets return data on success. A CPI caller would only see this if the deployed program was replaced by one that doesn’t emit return data. |
Anchor framework codes
Section titled “Anchor framework codes”Not Alea-specific, but you may see them:
| Code | Name | Meaning |
|---|---|---|
2001 | ConstraintHasOne | has_one = authority mismatch. Fires AFTER account deserialization, BEFORE the handler body. Wrong authority signer on an init/admin call. |
3010 | AccountNotSigner | An account declared Signer<'info> was passed without a signature. Fires earlier than 2001 during account resolution. |
Any code outside this table is not from Alea. Check the error’s program ID against ALEAydzHd4cN2EWcdHKp4hehAE4B88b16gqVtVqsck2U — if it doesn’t match, the error is from another program in your transaction (system program, SPL, your own program’s Anchor wrapper).
Decision tree — my verify is reverting
Section titled “Decision tree — my verify is reverting”Check these in order. Most production reverts land on one of them.
- Wrong drand chain. Check whatever
fetchBeacon/curlendpoint you’re hitting againstDRAND_CHAIN_HASH. If they differ, you get 6000 (pairing fails against evmnet pubkey). UsefetchBeaconfrom@alea-drand/sdk; it hits evmnet by default. - Stale round. If your consumer uses
is_round_recentyou’ll see your ownStaleBeacon(or equivalent) error, not an Alea code. If not — Alea accepts any round, so the failure is application-side. See Common Pitfalls §9. - Compute budget exceeded. Not a 6xxx code — Solana returns
Computational budget exceededin the logs. AddComputeBudgetProgram.setComputeUnitLimit({ units: 900_000 })as the first instruction.
If none of those fit and you’re seeing 6000, 6001, or 6002, re-fetch your (round, signature) pair against api.drand.sh directly.
Codes 6004 or 6006 in production mean something is off at the cryptographic or syscall layer. File an issue — these are not expected for valid drand beacons.
Related
Section titled “Related”- Common Pitfalls — narrative decision tree with context
- Rust SDK — error enum in Rust form
- TypeScript SDK —
ERRORSmap in TypeScript - Architecture — where each error gets raised in the verify flow