shardeum/shardeum · error · Error

Cannot run transaction: EIP 2930 is not activated.

Error message

Cannot run transaction: EIP 2930 is not activated.

What it means

runTx detected an access-list (type-1, EIP-2930) typed transaction but the chain's common does not have EIP-2930 activated at the current block. Typed tx support requires the corresponding hardfork (Berlin) to be active.

Source

Thrown at src/vm_v7/runTx.ts:116

  await evm.journal.cleanup()

  if (opts.reportAccessList === true) {
    evm.journal.startReportingAccessList()
  }

  await evm.journal.checkpoint()
  if (this.DEBUG) {
    debug('-'.repeat(100))
    debug(`tx checkpoint`)
  }

  // Typed transaction specific setup tasks
  if (opts.tx.supports(Capability.EIP2718TypedTransaction) && this.common.isActivatedEIP(2718) === true) {
    // Is it an Access List transaction?
    if (this.common.isActivatedEIP(2930) === false) {
      await evm.journal.revert('runTx: EIP 2930 not activated')
      const msg = _errorMsg('Cannot run transaction: EIP 2930 is not activated.', this, opts.block, opts.tx)
      throw new Error(msg)
    }
    if (opts.tx.supports(Capability.EIP1559FeeMarket) && this.common.isActivatedEIP(1559) === false) {
      await evm.journal.revert('runTx: EIP 1559 not activated')
      const msg = _errorMsg('Cannot run transaction: EIP 1559 is not activated.', this, opts.block, opts.tx)
      throw new Error(msg)
    }

    const castedTx = <AccessListEIP2930Transaction>opts.tx

    for (const accessListItem of castedTx.AccessListJSON) {
      evm.journal.addAlwaysWarmAddress(accessListItem.address, true)
      for (const storageKey of accessListItem.storageKeys) {
        evm.journal.addAlwaysWarmSlot(accessListItem.address, storageKey, true)
      }
    }
  }

  // chainId validation

View on GitHub (pinned to 0c454caf06)

Solutions

  1. Activate EIP-2930/Berlin in the chain's common/genesis config for the executing block height
  2. Send a legacy (type-0) tx instead if the chain intentionally stays pre-Berlin
  3. Verify common.isActivatedEIP(2930) before routing typed txs into runTx

Example fix

// before
const common = Common.custom({ chainId, genesis }, { hardfork: 'Istanbul' })

// after
const common = Common.custom({ chainId, genesis, hardforkHistory: { ...defaults, berlin: 0 } })
Defensive patterns

Strategy: validation

Validate before calling

if (tx.supports(Capability.EIP2930AccessList) && !common.isActivatedEIP(2930)) {
  downgradeToLegacyTx(tx)
}

Type guard

const isAccessListTx = (tx: TypedTransaction): tx is AccessListEIP2930Transaction =>
  tx.supports(Capability.EIP2930AccessList)

Prevention

When it happens

Trigger: Submitting a type-1 access-list tx on a chain whose common hardfork is pre-Berlin; genesis config missing the Berlin fork block; passing a custom Common with wrong fork schedule.

Common situations: Custom chain genesis that skips/omits Berlin; using a stale Common object after a hardfork config change; test commons built with default mainnet settings but a lower fork block.

Related errors


AI-assisted analysis of shardeum/shardeum@0c454caf06 (2026-08-28). Data as JSON: /api/errors/b3f4a6107ebf9549. Report an issue: GitHub.