Entros_docs
Reference

Errors

Error codes returned by each on-chain program.

Every program returns custom error codes via Anchor's #[error_code] macro. The codes start at 6000 and are assigned in declaration order; meanings are documented here. The error variants are append-only across versions, so existing codes are stable.

entros-anchor errors

CodeNameWhen
6000InvalidCommitmentSubmitted commitment is all zeros
6001UnauthorizedCaller is not the identity owner
6002ArithmeticOverflowInternal arithmetic operation overflowed
6003InvalidProtocolConfigProtocol config account owner or layout is wrong
6004InvalidIdentityStateIdentity state account failed to deserialize
6005IdentitySerializationFailedIdentity state account failed to serialize
6006VerificationResultWrongOwnerVerification result account is not owned by the verifier program
6007StaleVerificationResultVerification result account predates the cross-program binding patch
6008VerifierMismatchVerification result was signed by a different authority than the one in the request
6009ProofExpiredThe verification result is older than MAX_PROOF_AGE_SECS (10 minutes)
6010CommitmentMismatchThe proof's commitment_new does not match the submitted new commitment
6011PrevCommitmentMismatchThe proof's commitment_prev does not match the identity's current commitment
6012ResetCooldownActiveA reset_identity_state was attempted before the 7-day cooldown elapsed
6013UnauthorizedNewWalletCaller is not authorized by the old identity to claim a new wallet
6014ProofFromFutureThe verification result's verified_at is in the future relative to the cluster clock
6015MissingValidatorReceiptmint_anchor expected a preceding Ed25519 validator-signed receipt instruction; none was found
6016ReceiptValidatorMismatchMint receipt was signed by a key that does not match the registered validator pubkey
6017ReceiptCommitmentMismatchMint receipt commitment does not match the mint_anchor commitment argument
6018ReceiptWalletMismatchMint receipt wallet does not match the mint signer
6019ReceiptExpiredMint receipt has aged past MAX_RECEIPT_AGE_SECS (5 minutes)
6020ReceiptFromFutureMint receipt validated_at is in the future relative to the cluster clock
6021MalformedReceiptMessageMint receipt message has malformed length, layout, or cross-instruction references

The Receipt* family (6015–6021) only fires on the first-verification path. Re-verification (update_anchor) binds via the verifier-program VerificationResult PDA, not via the validator-signed mint receipt.

entros-verifier errors

CodeNameWhen
6000InvalidProofFormatProof bytes don't decode as a valid Groth16 proof
6001ProofVerificationFailedOn-chain pairing check failed
6002ChallengeExpiredThe associated challenge passed its expiry window
6003ChallengeAlreadyUsedThe challenge was already consumed by a successful verify_proof
6004InvalidPublicInputsPublic input count, encoding, or value bounds violated
6005ChallengeNotUsedA close_challenge was attempted on a challenge that has not been consumed
6006InvalidNonceThe challenge nonce is all zeros
6007ArithmeticOverflowInternal arithmetic operation overflowed

entros-registry errors

CodeNameWhen
6000InsufficientStakeValidator stake is below min_stake
6001ValidatorAlreadyRegisteredValidator state already exists for this authority
6002ValidatorNotActiveValidator state is registered but not currently active
6003UnauthorizedCaller is not the expected authority for this instruction
6004ArithmeticOverflowInternal arithmetic operation overflowed
6005InsufficientTreasuryBalanceWithdrawal amount exceeds the treasury's available balance
6006ProgramDataBytesProgramData account bytes are malformed or shorter than expected
6007WrongUpgradeAuthorityCaller is not the program's upgrade authority
6008InvalidProtocolConfigProtocol config bytes are malformed
6009InvalidValidatorPubkeyValidator pubkey supplied to set_validator_pubkey is the zero pubkey

entros-voter-weight errors

CodeNameWhen
6000InvalidRealmAuthorityCaller signing the registrar instruction is not the realm authority
6001MissingIdentityAccountVoter's identity account was not supplied via remaining_accounts
6002InvalidIdentityPdaIdentity account address does not match the expected PDA derivation
6003InvalidIdentityOwnerIdentity account is not owned by the Entros Anchor program
6004InvalidIdentityDataIdentity account data is shorter than the expected layout
6005InsufficientTrustScoreVoter's score is below the registrar's min_trust_score
6006VerificationExpiredVoter's last verification is older than max_verification_age
6007VoterWeightRecordRealmMismatchVoter weight record realm does not match the registrar
6008VoterWeightRecordMintMismatchVoter weight record mint does not match the registrar
6009VoterWeightRecordOwnerMismatchVoter weight record owner does not match the voter authority
6010RealmHasNoAuthorityThe realm has no authority configured; registrar updates require one
6011GoverningTokenOwnerSignerMismatchThe instruction's governing_token_owner does not match the signer
6012InvalidMaxVerificationAgemax_verification_age must be greater than zero
6013InvalidMaxVoterWeightmax_voter_weight must be greater than zero

SDK and HTTP errors

@entros/pulse-sdk returns a SubmissionResult from every submission helper:

type SubmissionResult = {
  success: boolean;
  txSignature?: string;
  attestationTx?: string;
  error?: string;
};

On success, txSignature is the verification transaction signature. attestationTx, when present, is the SAS attestation write. On failure, error carries the user-surfaceable message; the underlying program error code, when one exists, is included in that string and can be matched on.

Chain-side transaction failures

Since 1.5.0, the SDK throws when an on-chain transaction reverts. Earlier versions silently returned success: true for transactions that were included on chain but failed during execution—an easy way to ship a "verified!" UI for a tx that mutated nothing. The thrown error preserves the JSON InstructionError shape so callers can extract the Custom code:

const result = await session.complete(wallet, connection);
if (!result.success) {
  // result.error is one of:
  //   "Transaction failed on chain: {\"InstructionError\":[0,{\"Custom\":6011}]} (sig=...)"  // PrevCommitmentMismatch
  //   "Transaction failed on chain: {\"InstructionError\":[1,{\"Custom\":6015}]} (sig=...)"  // MissingValidatorReceipt
  //   "Transaction failed on chain: {\"InstructionError\":[0,\"InsufficientFundsForRent\"]}"
  //   ...or a non-chain failure (network, wallet rejected, etc.)
  const customMatch = result.error?.match(/"Custom":(\d+)/);
  if (customMatch) {
    const code = Number(customMatch[1]);
    if (code === 6012) showCooldownMessage();
    else if (code === 6011) showStaleBaselinePrompt();
    else showGenericError(`Program error ${code}`);
  } else {
    showGenericError(result.error);
  }
}

/attest requires wallet ownership proof

A request to the executor's /attest endpoint now requires wallet_address, nonce, signature, and message together on every call. Missing any of those returns:

{ "error": "wallet_ownership_required" }

with HTTP 400. The signed message format is Entros-ATTEST:{wallet_address}:{timestamp_secs}. The walletless attestation path was removed—wallets that cannot sign should not call /attest at all.

Response padding

Authenticated executor responses include an opaque _padding field of repeated ASCII characters that pads the JSON to a fixed byte length. Treat it as forward-compatible noise: ignore it on parse, do not surface it to users, do not assert on its content or length. It exists to defeat byte-length analysis of response classes.

Where to look next

On this page