---
title: "Delete topics from Kubernetes"
description: "Choose between the Orphan and Delete deletion policies when a KafkaTopic resource is removed, and allow deletion with an annotation."
url: https://monedula.dev/flock/docs/gitops/how-to/delete-topics-from-kubernetes/
---
When you delete a `KafkaTopic` resource, the operator's finalizer decides what happens to the Kafka topic, based on `spec.deletionPolicy`. `Orphan`, the default, stops managing the topic and leaves it on the broker. `Delete` removes the topic, but only once you approve it with an annotation.

## Before you start

- The operator. The CLI never deletes a topic: removing a `KafkaTopic` from the manifests you apply with the CLI leaves the topic in Kafka.
- For `Delete`, a connecting principal that may delete the topic and its ACLs, which takes `Delete` on the topic and `Alter` on the `Cluster` resource, or a super-user.

## Steps

### 1. Keep the topic with Orphan

This topic sets `deletionPolicy: Orphan` explicitly. Save it as `manifests/orphan-demo.yaml`:

```yaml
apiVersion: gitops.monedula.dev/v1alpha1
kind: KafkaTopic
metadata:
  name: orphan-demo
spec:
  clusterRef:
    name: shared
  topicName: orphan.demo
  partitions: 1
  deletionPolicy: Orphan
  config:
    cleanup.policy: compact
```

When a topic omits `deletionPolicy`, the operator uses the `KafkaCluster`'s `spec.defaults.topicDeletionPolicy`, and `Orphan` when that is not set either.

Apply the topic, wait until it is ready, then delete the resource:

```bash
kubectl apply -f manifests/orphan-demo.yaml
kubectl wait kafkatopic/orphan-demo --for=condition=Ready --timeout=120s
kubectl delete kafkatopic orphan-demo
```

The finalizer is removed at once, without contacting the broker. The topic `orphan.demo` and its ACLs stay in Kafka, unmanaged.

### 2. Delete the topic with Delete and approval

<Callout type="warning">
Deleting a `KafkaTopic` with `deletionPolicy: Delete` and the `allow-delete` annotation deletes the Kafka topic and its data, the topic's ACLs and the schema subjects whose content the topic manages.
</Callout>

This topic sets `deletionPolicy: Delete` and carries the approval annotation. Save it as `manifests/delete-demo.yaml`:

```yaml
apiVersion: gitops.monedula.dev/v1alpha1
kind: KafkaTopic
metadata:
  name: delete-demo
  annotations:
    gitops.monedula.dev/allow-delete: "true"
spec:
  clusterRef:
    name: shared
  topicName: delete.demo
  partitions: 1
  deletionPolicy: Delete
  config:
    cleanup.policy: compact
```

Apply it, wait until it is ready, then delete the resource:

```bash
kubectl apply -f manifests/delete-demo.yaml
kubectl wait kafkatopic/delete-demo --for=condition=Ready --timeout=120s
kubectl delete kafkatopic delete-demo
```

`kubectl delete` returns once the finalizer has cleaned up, in this order:

1. It deletes the topic's ACLs, except those another live `KafkaTopic` or `KafkaAccessPolicy` still declares.
2. It deletes the topic `delete.demo`.
3. If the topic declares schema content in `spec.schema`, it deletes the topic's subjects. Subjects in governance mode, where the topic manages only the compatibility level, are never deleted. If a subject cannot be deleted, the operator emits a `SubjectDeletionFailed` Warning event and still finishes the deletion.

On a cluster whose topic access also compiles to Confluent role bindings, the finalizer does not remove the topic's derived role bindings.

### 3. Approve a topic for deletion

Both the policy and the annotation are required. Without the annotation, deleting a `Delete` topic removes nothing: the resource stays in `Terminating` with a `DeleteNotApproved` Warning event, and adding the annotation to the waiting resource lets the deletion continue. Tenancy rules never block the deletion.

To delete a topic that currently uses `Orphan`, switch its policy to `Delete` and approve it before you delete the resource. For the topic `orders` in the namespace `monedula-demo`:

```bash
kubectl -n monedula-demo patch kafkatopic orders --type merge \
  -p '{"spec":{"deletionPolicy":"Delete"}}'
kubectl -n monedula-demo annotate kafkatopic orders \
  gitops.monedula.dev/allow-delete=true --overwrite

kubectl -n monedula-demo delete kafkatopic orders
```

For a `KafkaTopic` managed in Git, make the same two changes there.

### 4. Release a topic whose cleanup cannot run

A deletion can also wait because the cleanup cannot run:

- When the referenced `KafkaCluster` no longer exists, or its credentials cannot be read, the operator emits a `DeletionBlocked` Warning event. The annotation `gitops.monedula.dev/force-finalizer-removal: "true"` then removes the finalizer without any cleanup in Kafka; the topic and its ACLs stay.
- When Kafka rejects the cleanup, for example because the broker is down or the principal lacks a permission, the operator emits a `DeleteFailed` Warning event with the error and retries. To keep the topic and release the resource instead, switch its `deletionPolicy` to `Orphan`.

[Safety gates](/flock/docs/gitops/concepts/safety-gates/) lists the deletion policy of every other kind.

## Check it worked

```bash
kubectl get kafkatopic
```

Neither `orphan-demo` nor `delete-demo` is listed any more. On the broker, the topic `orphan.demo` still exists and `delete.demo` is gone. A `Delete` topic that stays in `Terminating` shows the reason in `kubectl describe kafkatopic <name>`.

## Related

- The [KafkaTopic reference](/flock/docs/gitops/reference/resources/kafka-topic/) lists `deletionPolicy`, and the [KafkaCluster reference](/flock/docs/gitops/reference/resources/kafka-cluster/) the cluster-wide default.
- [Delete resources safely with `--prune`](/flock/docs/gitops/how-to/delete-resources-safely/) covers what the CLI deletes.
- Runnable versions: [scenarios/13-topic-deletion-orphan](https://github.com/monedula-dev/monedula-gitops/tree/main/scenarios/13-topic-deletion-orphan) and [scenarios/14-topic-deletion-delete](https://github.com/monedula-dev/monedula-gitops/tree/main/scenarios/14-topic-deletion-delete)