> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arcium.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Account lifecycle and closing

> Close MXEs and computation definitions to reclaim rent: state machine, authority rules, errors, and common mistakes

Computation definitions and MXEs are onchain accounts that hold rent. When you no longer need them, close them to reclaim that rent. This page covers the close lifecycle, authority rules, and common errors. For a shorter command list, see the [deployment guide](/developers/deployment#closing-an-mxe-or-computation-definition).

<Note>
  This page covers long-lived MXE and computation-definition accounts. To close per-computation accounts after finalization, use [`claimComputationRent`](/developers/js-client-library#reclaiming-computation-rent).
</Note>

## Computation-definition lifecycle

A computation-definition account moves through the following states:

```mermaid theme={null}
stateDiagram-v2
    [*] --> IncompleteOnChain: init_computation_def<br/>(default OnChain)
    IncompleteOnChain --> Active: upload finalized<br/>(is_completed = true)
    [*] --> Active: init_computation_def<br/>(OffChain/Local)
    Active --> Deactivated: deactivate-computation-definition<br/>(irreversible; blocks new queues)
    Deactivated --> Closed: close-computation-definition<br/>(after TTL + no in-flight comps)
    IncompleteOnChain --> Closed: close-computation-definition<br/>(skips deactivate + TTL)
    Closed --> [*]
```

A default `CircuitSource::OnChain` comp def starts as `IncompleteOnChain` (`is_completed = false`) and is not queueable until upload finalization marks it complete. `CircuitSource::OffChain` and `CircuitSource::Local` comp defs initialize directly as `Active`.

The two-step gate exists so computations queued before deactivation can drain safely. Calling `deactivate-computation-definition` blocks new `queue_computation` calls immediately; existing queued computations must finalize or expire before closing succeeds.

## Deactivation TTL

`TTL_SLOTS = 180` (\~72s at 400 ms/slot). The TTL is identical to a Solana transaction's signature lifetime; the constant is shared on purpose. You can close the computation definition any time after `deactivation_slot + 180`.

## Authority

| Circuit source            | Who can deactivate / close                                    |
| ------------------------- | ------------------------------------------------------------- |
| `CircuitSource::OnChain`  | `upload_auth` (the keypair that uploaded the circuit buffers) |
| `CircuitSource::OffChain` | `mxe.authority`                                               |
| `CircuitSource::Local`    | `mxe.authority`                                               |

`close-mxe` always requires `mxe.authority`. Rent from every close goes back to the signer keypair (`-k`).

## Closing a computation definition

```bash theme={null}
# 1. Mark the computation definition for closure (irreversible: blocks new queues immediately)
arcium deactivate-computation-definition \
  -o <computation-definition-offset> \
  -p <mxe-program-id> \
  -k <path-to-your-keypair> \
  --rpc-url <your-rpc-url>

# 2. After the TTL (180 slots, ~72s) has passed and no in-flight comps remain, close it
arcium close-computation-definition \
  -o <computation-definition-offset> \
  -p <mxe-program-id> \
  -c <cluster-offset> \
  -k <path-to-your-keypair> \
  --rpc-url <your-rpc-url>
```

`close-computation-definition` is the only close command that needs `--cluster-offset` (`-c`): the program enforces `mxe.cluster == cluster_offset`.

### Incomplete onchain comp defs skip the TTL

If a `CircuitSource::OnChain` upload was aborted before finishing, the comp def remains `Incomplete` and can be closed immediately, without deactivating first. This is the only way out of the two-step gate.

### Raw circuit buffers (onchain circuits only)

`CircuitSource::OnChain` comp defs also store circuit bytes in separate buffer accounts indexed by `raw_circuit_index`. Close each buffer separately with the MXE authority keypair:

```bash theme={null}
arcium close-computation-definition-buffers \
  -o <computation-definition-offset> \
  -p <mxe-program-id> \
  -i <raw-circuit-index> \
  -k <path-to-your-keypair> \
  --rpc-url <your-rpc-url>
```

Buffers can be closed when the parent comp def is `Deactivated` *or* still `Incomplete`. Unlike deactivating or closing the parent `OnChain` comp def, buffer close requires `mxe.authority`. Offchain and `Local` comp defs store no buffers, so this step does not apply to them.

### Reserved comp defs

Each MXE has reserved internal computation definitions (e.g. `MxeKeygen`, `MxeKeyRecoveryInit`). You cannot close these directly with `close-computation-definition`: attempting it errors with `CannotCloseReservedComputationDefinition`. They are closed atomically by `close-mxe`.

### LUT entries persist across close

Closing a comp def does **not** close its address-lookup-table entry. Re-initializing a comp def at the same offset reuses the existing LUT slot, so close + reinit cycles do not pay rent for a new LUT.

## Closing an MXE

```bash theme={null}
arcium close-mxe \
  -p <mxe-program-id> \
  -k <path-to-your-keypair> \
  --rpc-url <your-rpc-url>
```

`close-mxe` enforces several preconditions before closing:

1. MXE must not be in `Migration` state: abort or resume the migration first.
2. Keygen must be finalized (`MxeKeygenNotFinalized` otherwise).
3. Every user-defined computation definition must be closed first. Only reserved MXE computation definitions may remain (`MxeKeygen` and, if present, `MxeKeyRecoveryInit`).
4. Signer must be `mxe.authority`.

When the preconditions pass, `close-mxe` closes the MXE account, the reserved keygen comp def, the keygen computation account, the recovery cluster account, and (if present) the key-recovery-init comp def and computation, all in one transaction. Rent for every closed account returns to the signer.

## Error reference

Anchor program errors are reported as `Error Code: <number>` where the number is `6000 + <internal offset>`. Internal offsets and meanings:

| Internal | Anchor surfaced | Name                                         | Meaning                                           |
| -------- | --------------- | -------------------------------------------- | ------------------------------------------------- |
| 0        | 6000            | `InvalidAuthority`                           | Signer is not the authority for this account      |
| 9        | 6009            | `MxeHasComputationDefinitions`               | `close-mxe` blocked: user comp defs remain        |
| 10       | 6010            | `MxeKeygenNotFinalized`                      | `close-mxe` blocked: keygen not yet finalized     |
| 306      | 6306            | `ComputationDefinitionDeactivated`           | Cannot deactivate twice                           |
| 307      | 6307            | `ComputationDefinitionNotDeactivated`        | Call `deactivate-computation-definition` first    |
| 308      | 6308            | `ComputationDefinitionHasActiveComputations` | A pre-deactivation computation is still in flight |
| 309      | 6309            | `ComputationDefinitionTtlNotPassed`          | Wait until `deactivation_slot + 180`              |
| 310      | 6310            | `CannotCloseReservedComputationDefinition`   | Reserved offsets close atomically via `close-mxe` |
| 725      | 6725            | `CannotCloseMxeDuringMigration`              | Abort or resume the cluster migration first       |

## Common mistakes

* **"`ComputationDefinitionTtlNotPassed` (6309)"**: you're inside the 180-slot window after deactivation. Wait \~72 s and retry.
* **"`ComputationDefinitionHasActiveComputations` (6308)"**: a computation queued before `deactivation_slot` is still in the execpool. Computations themselves expire after 180 slots; wait for it to finalize or expire and retry.
* **"`ComputationDefinitionNotDeactivated` (6307)"**: you skipped `deactivate-computation-definition`. Active comp defs cannot be closed directly (the only exception is `Incomplete` `OnChain` comp defs).
* **"`CannotCloseReservedComputationDefinition` (6310)"**: you targeted a reserved offset (`MxeKeygen`, `MxeKeyRecoveryInit`). Run `close-mxe` instead; reserved offsets close atomically as part of it.
* **"`MxeHasComputationDefinitions` (6009)"**: `close-mxe` requires every user-defined comp def to be closed first. Only reserved MXE computation definitions may remain (`MxeKeygen` and, if present, `MxeKeyRecoveryInit`).
* **"`CannotCloseMxeDuringMigration` (6725)"**: there's a `migrate-cluster` in flight. `--resume` or `--abort` it, then retry.
* **"`InvalidAuthority` (6000)"**: for comp defs, `OnChain` accepts `upload_auth` while `OffChain`/`Local` require `mxe.authority`. `close-mxe` always requires `mxe.authority`.
* **"`InvalidAuthority` (6000)" on buffer close**: `close-computation-definition-buffers` always requires `mxe.authority`, even for `OnChain` comp defs uploaded by a different `upload_auth`.
* **"`close-computation-definition-buffers` did nothing"**: your comp def is `OffChain` or `Local`. There are no buffer accounts to close; skip the step.
* **"Forgot `--cluster-offset` on `close-computation-definition`"**: only that command needs `-c`; the program rejects mismatches against `mxe.cluster`.

## What's next?

<CardGroup cols={2}>
  <Card title="Deployment" icon="rocket" href="/developers/deployment">
    Deploy, migrate, and close MXEs from the CLI.
  </Card>

  <Card title="Computation definition accounts" icon="file-lines" href="/developers/program/computation-def-accs">
    How comp defs are created and initialized.
  </Card>
</CardGroup>
