Skip to content

What cannot be deleted

Some things a run reports as residue rather than as failures, because the platform does not offer a way to delete them within the run. Knowing which is which is the difference between reading a plan correctly and chasing a bug that is not there.

What cannot be deleted

Not every resource this tool finds can actually be removed on the run that finds it. The platform itself imposes a handful of limitations, each reported through a machine-readable scope.Reason* value so an operator never has to guess why something is still there:

  • Vault, KmsKey and VaultSecret scheduled-deletion window (scope.ReasonScheduledDeletion). OCI enforces a 7-30 day deletion window on vaults and keys, and a 1-30 day one on secrets, that a run cannot shorten. oci-nuke schedules the deletion and reports the resource as a leftover rather than treating the delay as a failure. A secret's name stays taken until its window ends, which is why secrets default to the one-day floor.
  • RetentionRule permanent lock (scope.ReasonRetentionLocked). A retention rule locks permanently 14 days after creation and, once locked, can only be removed by deleting the bucket it belongs to — never directly. Because Bucket declares RetentionRule as a dependency, a locked rule also blocks its own bucket from being deleted this run.
  • TagNamespace retire-then-cascade (no dedicated Reason — a two-step Remove()). A tag namespace cannot be deleted directly; it must first be retired (IsRetired: true), and the cascade-delete of every tag definition and value beneath it runs asynchronously afterward. oci-nuke performs both steps, but the cascade can still be in flight when a run ends.
  • MySQLDbSystem service-level delete protection (scope.ReasonDeleteProtected). When DeletionPolicy.IsDeleteProtected is set on the DB system, OCI's own service refuses the delete — independent of any oci-nuke configuration, and not bypassed by --force.
  • Compartment that will not be empty (scope.ReasonCompartmentNotEmpty). A compartment with a blocklisted descendant can never physically empty, so oci-nuke never attempts to delete it. Nor does it attempt one that still holds anything the run will leave behind — a scheduled deletion, a protected or too-young resource, backup residue, a child compartment that stays — or one whose DeleteCompartment OCI refused while the run had nothing of its own in it. The plan already shows such a compartment as skipped and names what holds it; a later run deletes it once that is gone.
  • Database backup residue for AutonomousDatabase, DbSystem, and MySQLDbSystem (scope.ReasonBackupResidue). Terminating one of these database types leaves an automatic post-termination backup behind that Oracle itself retains for 72 hours to 95 days. oci-nuke enumerates these backups for visibility but never attempts to delete them — this is a deliberate scope decision, not a bug.

See docs/resources/ and each type's Filter() doc comment in resources/ for the authoritative, per-type detail behind each bullet above.