## TL;DR
A dnf transaction interrupted mid-flight can leave duplicate, half-installed, or unconfigured packages, so do not start a new update on top of it. Recover in order: check dnf history and the transaction state, run the distribution recovery steps - complete or roll back the interrupted transaction, remove duplicates, and rebuild the rpm database if it complains - then run a full check before resuming patching. Change the agent so window ends stop new transactions from starting and let a running transaction finish or reach a safe checkpoint.

```text
agent failed when patch window closed mid transaction and dnf left system half upgraded
```

## Use this when
- A host shows duplicate packages, failed transaction messages, or inconsistent rpm state after a patch window closed during a dnf run.
- The agent log shows the transaction was killed, the session timed out, or the host lost power mid transaction.
- dnf check or a test transaction reports problems referencing the interrupted run.

## Not for this skill when
- The dnf transaction completed cleanly and one package service fails afterward. Fix that service, not the transaction state.
- The window closed before any transaction started. There is nothing to recover; simply reschedule.

## Steps
1. Freeze further patching on the host and gather the transaction evidence: read dnf history for the interrupted transaction and its state, check for any still running package processes, and confirm no other administrator session is mid transaction. Record the transaction identifier and the package count it touched, because recovery decisions depend on how far it got. Verify: patching is paused on the host and the interrupted transaction is identified with its scope documented
2. Assess consistency with the built-in checks before changing anything: run dnf check and an rpm database verification, and note duplicate packages, unsatisfied dependencies, or database errors. Duplicates are the signature of an interrupted install where the new version installed but the old version cleanup never ran. Verify: the checks produce a concrete list of duplicates and inconsistencies, or a database problem that must be repaired first
3. Recover the transaction using the distribution supported path: if dnf offers to complete or redo the transaction, take it; use dnf history undo or redo for the interrupted transaction where appropriate, and remove exact duplicate older packages with the duplicate cleanup tooling your distribution provides, such as package-cleanup equivalents or dnf remove duplicates functionality. Work on a console session that will not be timed out again. Verify: the interrupted transaction is completed or undone, duplicates are removed, and dnf check returns clean or a much smaller, specific problem
4. Rebuild trust in the package state: run a full dnf distro sync or update dry run to see the resolver view of the system, complete any pending configuration, and reboot if kernel or core libraries were part of the interrupted set, since half-updated libraries can leave running processes on deleted files. Verify: a dry run shows a coherent package set and the host reboots cleanly if core components were involved
5. Fix the agent window behavior so this cannot recur: the agent must check remaining window time against the estimated transaction duration before starting, must never kill a transaction at window end but instead let it finish while blocking new work, and must record a transaction in progress state durably so a restarted agent recovers it instead of starting a second transaction on top. Verify: a simulated window close during a test transaction lets the transaction finish safely and the agent records and recovers its state correctly

## Why it happens
RPM transactions are designed to be atomic in intent but not in execution: packages are installed, configured, and old versions erased in sequence, and an interruption between those phases leaves the database describing a system that is part old and part new, including the classic duplicate package state where the erase never happened. Starting another transaction on that foundation compounds the inconsistency because the resolver trusts the database. Recovery tools work because they reason about the recorded transaction as a whole. The agent lesson is scheduling discipline: a maintenance window is a deadline for starting work, never a license to kill package transactions mid-flight.

## Variants and edge cases
### Interruption was a host power loss or hypervisor snapshot revert
Treat database integrity as suspect: verify the rpm database, and if the host was reverted, reconcile its package state against the tracker, which may believe updates the revert undid.

### Duplicates involve the kernel
Kernel duplicates are often normal because multiple kernels coexist by design. Exclude kernel packages from duplicate panic and use the installonly packages configuration to judge them.

### Agent window is enforced by an external killer
If infrastructure force-kills sessions at window end, the agent must start transactions only when the full estimated duration fits, with margin, and checkpoint its intent durably before starting.

Compatibility: Applies to dnf based systems including Red Hat Enterprise Linux 8 and 9, Rocky Linux, AlmaLinux, and Fedora.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_gRkxtgaoveuR-Cxrg2Cm7Q
