Introduction

Yum and DNF package operations can fail for many reasons — lock files, repository errors, dependency conflicts, network timeouts, or disk space. This guide covers systematic troubleshooting patterns for Ansible playbooks that manage packages on RHEL, CentOS, Fedora, and other Red Hat family systems.

Common Errors and Solutions

1. Yum Lock File (Another Process Running)

Another app is currently holding the yum lock; waiting for it to exit...
- name: Wait for yum lock to be released
  ansible.builtin.wait_for:
    path: /var/run/yum.pid
    state: absent
    timeout: 300

- name: Install package
  ansible.builtin.yum:
    name: httpd
    state: present

Or kill stale processes:

- name: Kill stale yum processes
  ansible.builtin.shell: |
    if [ -f /var/run/yum.pid ]; then
      kill -9 $(cat /var/run/yum.pid) 2>/dev/null || true
      rm -f /var/run/yum.pid
    fi
  changed_when: false

- name: Install package
  ansible.builtin.yum:
    name: httpd
    state: present

2. Repository Errors

Cannot find a valid baseurl for repo: base/7/x86_64
- name: Clean yum cache
  ansible.builtin.command: yum clean all
  changed_when: true

- name: Rebuild yum cache
  ansible.builtin.yum:
    name: "*"
    state: latest
    update_cache: true
  when: false  # Just update cache
  ignore_errors: true

# Better approach — use the update_cache parameter
- name: Install with fresh cache
  ansible.builtin.yum:
    name: httpd
    state: present
    update_cache: true

3. Dependency Conflicts

Error: Package: httpd-2.4.6-97.el7.x86_64 requires: httpd-tools = 2.4.6-97.el7
- name: Install package allowing dependency resolution
  ansible.builtin.yum:
    name: httpd
    state: present
    skip_broken: true

# Or force install with all dependencies
- name: Install with dependencies
  ansible.builtin.yum:
    name:
      - httpd
      - httpd-tools
      - mod_ssl
    state: present

4. GPG Key Errors

Public key for package.rpm is not installed
- name: Import RPM GPG key
  ansible.builtin.rpm_key:
    key: https://packages.example.com/RPM-GPG-KEY-example
    state: present

- name: Install package
  ansible.builtin.yum:
    name: example-package
    state: present
    disable_gpg_check: false  # Keep GPG enabled in production

5. Disk Space Issues

Error: Insufficient disk space
- name: Check disk space before installing
  ansible.builtin.assert:
    that:
      - ansible_mounts | selectattr('mount', 'equalto', '/') | map(attribute='size_available') | first > 1073741824
    fail_msg: "Less than 1 GB free on /. Cannot install packages."
    success_msg: "Sufficient disk space available."

- name: Clean old packages to free space
  ansible.builtin.yum:
    autoremove: true

- name: Clean yum cache
  ansible.builtin.command: yum clean all
  changed_when: true

Retry Pattern

- name: Install package with retry
  ansible.builtin.yum:
    name: httpd
    state: present
  register: yum_result
  retries: 3
  delay: 10
  until: yum_result is not failed

Error Handling Patterns

Block/Rescue

- name: Package installation with fallback
  block:
    - name: Install from primary repo
      ansible.builtin.yum:
        name: mypackage
        state: present

  rescue:
    - name: Clean cache and retry
      ansible.builtin.command: yum clean all
      changed_when: true

    - name: Retry installation
      ansible.builtin.yum:
        name: mypackage
        state: present
        update_cache: true

Conditional Error Handling

- name: Install package
  ansible.builtin.yum:
    name: httpd
    state: present
  register: install_result
  ignore_errors: true

- name: Handle failure
  ansible.builtin.debug:
    msg: "Installation failed: {{ install_result.msg }}"
  when: install_result is failed

- name: Fail with helpful message
  ansible.builtin.fail:
    msg: |
      Package installation failed. Check:
      1. Repository connectivity: yum repolist
      2. Disk space: df -h
      3. Lock files: ls /var/run/yum.pid
  when: install_result is failed

Yum vs DNF Module

Featureansible.builtin.yumansible.builtin.dnf
RHEL/CentOS 7✓✗
RHEL/CentOS 8+✓ (wrapper)✓ (native)
Fedora✓ (wrapper)✓ (native)
Module groups✓✓
skip_broken✓✓
allowerasing✗✓
PerformanceSlowerFaster

Cross-Platform Pattern

- name: Install package (works on all RHEL family)
  ansible.builtin.package:
    name: httpd
    state: present

The package module auto-selects yum or dnf based on the OS.

Check Mode (Dry Run)

# Test without making changes
ansible-playbook playbook.yml --check --diff
- name: Install with check mode awareness
  ansible.builtin.yum:
    name: httpd
    state: present
  check_mode: "{{ ansible_check_mode }}"

Conditional Reboots

Only reboot after kernel updates, not regular package installs:

- name: Update all packages
  ansible.builtin.yum:
    name: "*"
    state: latest
  register: yum_update

- name: Check if reboot is needed
  ansible.builtin.command: needs-restarting -r
  register: reboot_check
  failed_when: false
  changed_when: reboot_check.rc == 1

- name: Reboot if kernel was updated
  ansible.builtin.reboot:
    reboot_timeout: 600
    msg: "Rebooting for kernel update"
  when: reboot_check.rc == 1

Diagnostic Commands

- name: Gather yum diagnostic info
  ansible.builtin.shell: |
    echo "=== Repo List ==="
    yum repolist -v
    echo "=== Disk Space ==="
    df -h
    echo "=== Lock Files ==="
    ls -la /var/run/yum.pid 2>/dev/null || echo "No lock file"
    echo "=== Recent Yum Log ==="
    tail -20 /var/log/yum.log
  register: yum_diag
  changed_when: false

- name: Show diagnostics
  ansible.builtin.debug:
    var: yum_diag.stdout_lines

Conclusion

Most Yum/DNF failures in Ansible come from lock files, stale caches, or dependency conflicts — not from issues requiring a reboot. Use update_cache: true for stale repos, retries with until for transient network failures, block/rescue for fallback logic, and needs-restarting -r to determine if a reboot is actually needed. Always test with --check mode first.