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

# Deactivate an executor

> Take an executor out of service — revoke its key or delete it permanently

You have two ways to take an executor out of service. **Revoke its API key** is a quick, reversible cut: the executor can no longer reach Novacula and goes offline, but its row and history stay. **Delete the executor** is permanent and only works once the executor hosts no nodes.

When in doubt, revoke the key. You can always issue a new one. A deleted executor is gone for good.

Deactivated executors are **hidden by default** in the **Executors** list so the view stays focused on what's in service. Turn on the explicit filter to show them again.

## Before you start

* You need the **owner** or **admin** role.
* To delete an executor, first delete every node it hosts.

## Revoke the API key

Use this when you want the executor to stop reaching Novacula right away — a compromised host, a colo you're shutting down — without losing the executor or its history.

<Steps>
  <Step title="Open API keys">
    In the sidebar, open **API keys**.
  </Step>

  <Step title="Find the key">
    Locate the key the executor uses. The **last used** column helps you match it to the right executor.
  </Step>

  <Step title="Revoke it">
    Open the key's menu and choose **Revoke**. Its status changes to **Revoked**.
  </Step>
</Steps>

What happens next:

* The executor can no longer reach Novacula and shows **offline** within \~30 seconds.
* Its nodes stay in Novacula in their last reported state. They show as unreachable; any lifecycle action you queue applies only once the executor reconnects.
* The processes on the host keep running — the executor doesn't stop just because it can't reach Novacula.

To bring the executor back later, issue a new key from **API keys** and apply it on the host.

## Delete the executor

Use this when you're decommissioning the host for good.

### 1. Drain its nodes

You can't delete an executor that still hosts nodes. For each node, **stop** it, then **delete** it — see the [node lifecycle](/docs/nodes/node-lifecycle).

Deleting a node removes its data, and there's no automatic transfer to another executor. If you need to keep the data, copy the node's data directory off the host before you delete it.

### 2. Delete the row

Open **Executors**, select the executor, and choose **Delete**. The row is removed and the name frees up — you can reuse it for a new executor. The API key tied to the executor is revoked at the same time.

### 3. Clean up your infrastructure

Novacula can't reach into your infrastructure — the executor's daemon and the node processes keep running until you remove them yourself.

<Warning>
  **Remove the nodes before the executor.** Draining them in step 1 already does this. If you remove the operator first, its `BlockchainNode` objects get stuck `Terminating` — nothing is left to drop their `novacula.io/blockchainnode-cleanup` finalizer.
</Warning>

#### Agent (bare metal / VM)

Run on the host as root. The agent's built-in `uninstall` removes only its own daemon — the per-node units, data directory, and firewall table survive it, so remove those too.

<Steps>
  <Step title="Stop the per-node units">
    They keep running after the agent is gone. List them, then disable and remove the unit files:

    ```bash theme={null}
    systemctl list-units --type=service 'nvcl-*'
    systemctl disable --now 'nvcl-*.service'
    rm -f /etc/systemd/system/nvcl-*.service
    ```
  </Step>

  <Step title="Remove the agent, its firewall table, and its files">
    ```bash theme={null}
    sudo novacula-agent uninstall
    nft delete table inet nvcl 2>/dev/null || true
    systemctl daemon-reload
    sudo rm -rf /etc/novacula /var/lib/novacula /opt/novacula
    ```
  </Step>

  <Step title="Verify it's clean">
    Each command should return nothing (or "not found"):

    ```bash theme={null}
    systemctl list-units --type=service 'nvcl-*'
    systemctl status novacula-agent.service
    nft list table inet nvcl
    ls /var/lib/novacula /etc/novacula
    ```
  </Step>
</Steps>

If the agent fronted RPC with a managed Caddy, its Caddy config and sites for those nodes may remain — remove them separately.

#### Operator (Kubernetes)

The CRD and per-node resources outlive a plain `helm uninstall`, so clean up in order.

<Steps>
  <Step title="Delete the nodes">
    Do this while the operator is still running — its finalizer tears down each node's `StatefulSet`, PVC, `Service`, `Ingress`, and `NetworkPolicy`:

    ```bash theme={null}
    kubectl delete blockchainnodes --all -n <namespace> --wait=true
    ```
  </Step>

  <Step title="Remove the operator release">
    Removes the `Deployment`, `ServiceAccount`, RBAC, `Secret`, and `Service`:

    ```bash theme={null}
    helm uninstall <release> -n <namespace>
    ```
  </Step>

  <Step title="Delete the CRD">
    The operator created it itself, so Helm never managed it:

    ```bash theme={null}
    kubectl delete crd blockchainnodes.novacula.io
    ```
  </Step>

  <Step title="Verify it's clean">
    Each should return empty; optionally drop the namespace too:

    ```bash theme={null}
    kubectl get crd | grep novacula.io
    kubectl get clusterrole,clusterrolebinding | grep <release>
    kubectl get all,ingress,networkpolicy,pvc -n <namespace>
    kubectl delete namespace <namespace>
    ```
  </Step>
</Steps>

**Stuck in `Terminating`?** If the operator was removed before its nodes, clear the finalizer by hand:

```bash theme={null}
kubectl patch blockchainnode <name> -n <namespace> \
  --type=merge -p '{"metadata":{"finalizers":[]}}'
```

Node PVCs are deleted with the `StatefulSet` (`persistentVolumeClaimRetentionPolicy.whenDeleted: Delete`); if a PV uses the `Retain` reclaim policy, delete the released PVs separately.

<Note>
  Neither `uninstall` nor `helm uninstall` revokes the executor's API key or notifies Novacula — deleting the executor row (step 2) is what revokes the key. For the full install/uninstall walkthrough, see the [bare metal](/recipes/provision-on-bare-metal) or [Kubernetes](/recipes/provision-on-kubernetes) recipe.
</Note>
