Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Ansible By James Joyner IV · · 8 min read

Ansible Error Guide: 'No package matching is available' — Fix Package Install Failures

Quick answer

Fix Ansible's 'No package matching X is available' error by correcting package names per distro, refreshing repo metadata, and enabling the right repositories.

Part of the Ansible Playbook & Module Errors hub
  • #ansible
  • #automation
  • #troubleshooting
  • #errors
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

Ansible’s package modules raise this when the requested package name cannot be found in any enabled repository on the target host:

fatal: [db01]: FAILED! => {"changed": false, "msg": "No package matching 'python3-psycopg2' is available"}

The apt module produces a close variant of the same problem:

fatal: [db01]: FAILED! => {"changed": false, "msg": "No package matching 'nginx-full' is available"}

The task failed at the package-resolution step: the module reached the package manager, but the manager’s index has no candidate for that name. It is a naming or repository problem, not a connectivity or permission one.

Symptoms

  • A package/apt/dnf/yum task fails with No package matching '<name>' is available.
  • The same play works on one distro/version and fails on another.
  • Installing the package by hand with apt-get install <name> also reports it is not found.
  • The package exists but only after enabling an extra repository (EPEL, universe, a vendor repo).
  • Stale metadata: the package was published recently but the host’s cache predates it.

Common Root Causes

  • Distro-specific package name — the same software is named differently across families (e.g. python3-psycopg2 vs python3-psycopg2cffi, httpd vs apache2).
  • Stale package index — the target’s metadata cache is old; the package exists upstream but not in the cached index.
  • Repository not enabled — the package lives in EPEL, universe, or a vendor repo that is not configured on the host.
  • Wrong module for the OS — using apt on a RHEL host or yum on Debian, so the name space is entirely wrong.
  • Version pin that does not existname: nginx=1.999 where that exact version is not a candidate.
  • Architecture mismatch — a package with no candidate for the host’s architecture.

Diagnostic Workflow

Confirm the exact name the package manager knows by searching on the target itself:

ansible db01 -i inventory -b -m shell -a "apt-cache search psycopg2 || dnf search psycopg2"

Refresh metadata and check for a candidate, distinguishing “unknown name” from “stale cache”:

ansible db01 -i inventory -b -m shell -a "apt-get update && apt-cache policy python3-psycopg2"

Verify the OS family so you know which module and name space applies:

ansible db01 -i inventory -m setup -a "filter=ansible_distribution*"

Write the task to update the cache and, where needed, branch on distribution:

- name: Install PostgreSQL client library (Debian family)
  ansible.builtin.apt:
    name: python3-psycopg2
    state: present
    update_cache: true          # refresh index so a new package resolves
  when: ansible_os_family == "Debian"

- name: Install PostgreSQL client library (RedHat family)
  ansible.builtin.dnf:
    name: python3-psycopg2
    state: present
    update_cache: true
  when: ansible_os_family == "RedHat"
ansible-playbook -i inventory install.yml --limit db01

Example Root Cause Analysis

A role that installed python3-psycopg2 worked across the Ubuntu fleet but failed on two new AlmaLinux hosts with No package matching 'python3-psycopg2' is available. ansible db01 -m setup -a "filter=ansible_distribution*" confirmed those hosts were RedHat-family, where the base repos did not carry that package — it lives in a repo that had not been enabled. Running dnf search psycopg2 on the host returned nothing until EPEL was added.

The fix was twofold: gate the install task on ansible_os_family so the correct name and module ran per distro, and add a prior task to enable EPEL on RedHat-family hosts before the install. After enabling the repo and refreshing metadata, the candidate resolved and the task succeeded. The broader lesson: a package name is not portable across distro families, and a role that installs packages must either branch on the OS or use a per-distro variable for the name.

Prevention Best Practices

  • Branch package tasks on ansible_os_family/ansible_distribution, or map names through per-distro variables, instead of assuming one name works everywhere.
  • Set update_cache: true (apt) or refresh metadata so a recently published package is not missed due to a stale index.
  • Enable required repositories (EPEL, universe, vendor repos) in an earlier task before installing packages that depend on them.
  • Avoid hard version pins unless the exact version is guaranteed to be a candidate on every target.
  • Test roles against every distro/version in the fleet in CI, not just the most common one.

Quick Command Reference

# Search for the real package name on the target
ansible <host> -i inv -b -m shell -a "apt-cache search <term> || dnf search <term>"

# Refresh metadata and inspect the candidate
ansible <host> -i inv -b -m shell -a "apt-get update && apt-cache policy <name>"

# Identify the distro family
ansible <host> -i inv -m setup -a "filter=ansible_distribution*"

# List enabled repos (RedHat family)
ansible <host> -i inv -b -m shell -a "dnf repolist"

Conclusion

“No package matching X is available” is a naming or repository problem: the package manager simply has no candidate for that name on that host. Confirm the real name per distro family, refresh the metadata cache, and enable the repositories the package lives in — then branch your task on the OS so the same role stays correct across a mixed fleet. Portable package installs come from explicit per-distro names, not from hoping one name works everywhere.

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.