linera-io/linera-protocol · error · ChainError

All operations on this chain must be from one of the followi

Error message

All operations on this chain must be from one of the following applications: {0:?}

What it means

check_app_permissions (linera-chain/src/chain.rs:1585) enforces the chain's ApplicationPermissions: when the execute_operations allowlist is set (via the SetApplicationPermissions admin operation), every non-exempt operation's application must be on the list (chain.rs:1601-1607). Exempt system operations (e.g., changing the permissions themselves) bypass the check and additionally clear the mandatory-application requirement.

Source

Thrown at linera-chain/src/chain.rs:1602

    ))]
    fn check_app_permissions(
        app_permissions: &ApplicationPermissions,
        block: &ProposedBlock,
    ) -> Result<(), ChainError> {
        let mut mandatory = app_permissions
            .mandatory_applications
            .iter()
            .copied()
            .collect::<HashSet<ApplicationId>>();
        for transaction in &block.transactions {
            match transaction {
                Transaction::ExecuteOperation(operation)
                    if operation.is_exempt_from_permissions() =>
                {
                    mandatory.clear()
                }
                Transaction::ExecuteOperation(operation) => {
                    ensure!(
                        app_permissions.can_execute_operations(&operation.application_id()),
                        ChainError::AuthorizedApplications(
                            app_permissions.execute_operations.clone().unwrap()
                        )
                    );
                    if let Operation::User { application_id, .. } = operation {
                        mandatory.remove(application_id);
                    }
                }
                Transaction::ReceiveMessages(incoming_bundle)
                    if incoming_bundle.action == MessageAction::Accept =>
                {
                    for pending in incoming_bundle.messages() {
                        if let Message::User { application_id, .. } = &pending.message {
                            mandatory.remove(application_id);
                        }
                    }
                }

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Only submit operations from applications on the chain's allowlist (query application_permissions from chain state)
  2. To enable a new app, submit the exempt ChangeApplicationPermissions system operation first to extend the allowlist, then send the operation
  3. If the restriction is wrong, update permissions via an exempt admin operation in its own step

Example fix

// before: submitting a restricted app's operation directly
client.submit_block(vec![Transaction::ExecuteOperation(user_op)]).await?; // AuthorizedApplications

// after: widen the allowlist first, then submit
client.submit_block(vec![Transaction::ExecuteOperation(Operation::system(
    SystemOperation::ChangeApplicationPermissions(ApplicationPermissions {
        execute_operations: Some(new_set), ..
    }),
))]).await?;
client.submit_block(vec![Transaction::ExecuteOperation(user_op)]).await?;
Defensive patterns

Strategy: validation

Validate before calling

// Check permissions client-side before submitting (mirrors chain.rs:1601-1607):
let perms = client.chain_info(chain_id).await?.info.application_permissions;
for op in block.operations() {
    if !op.is_exempt_from_permissions()
        && !perms.can_execute_operations(&op.application_id())
    {
        anyhow::bail!("operation app {:?} not in execute_operations allowlist", op.application_id());
    }
}

Type guard

fn operation_allowed(perms: &ApplicationPermissions, op: &Operation) -> bool {
    op.is_exempt_from_permissions() || perms.can_execute_operations(&op.application_id())
}

Try / catch

match result {
    Err(ChainError::AuthorizedApplications(allowed)) => {
        // `allowed` lists the permitted apps: either switch to one of them, or first
        // submit an exempt ChangeApplicationPermissions op to extend the allowlist
    }
    other => other?,
}

Prevention

When it happens

Trigger: Submitting a user operation whose application_id is not in the allowlist configured on the chain; calling a system operation that is not exempt (not in is_exempt_from_permissions) on a restricted chain; a chain restricted to app X receiving a transfer initiated by app Y.

Common situations: Regulated or app-curated chains configured with execute_operations permissions; deploying a new app version and forgetting to allowlist it; wallet clients defaulting to a fungible-token app not included in the chain's permission set.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/0676b890bdc2af14. Report an issue: GitHub.