skip to content

On a RHEL 8 or 9 host, `yum install httpd` still works even though the system's package manager is dnf. What is the `yum` command on such a host, and what happened to /etc/yum.conf and /etc/yum.repos.d?

level: juniorimportance: must knowfreq 62%

answer

  1. not a separate program any more
  2. follow the symlink
  3. same target as /usr/bin/dnf
  4. config paths kept for compatibility
  5. repo directory never moved

basics

~20 s

On RHEL 8 and 9 the yum command is a symlink to dnf-3, so running yum runs dnf. /etc/yum.conf is a symlink to /etc/dnf/dnf.conf, and /etc/yum.repos.d is still the directory dnf reads repository files from.

solid answer

~40 s

On RHEL 8 and 9 there is no separate yum program any more. `/usr/bin/yum` is a symbolic link to `/usr/bin/dnf-3` — the same target `/usr/bin/dnf` points at — so every `yum` command you type is dnf parsing a compatible command line. The compatibility extends to configuration: `/etc/yum.conf` is a symlink to `/etc/dnf/dnf.conf`, and dnf's default `reposdir` is still `/etc/yum.repos.d`, so decade-old `.repo` files keep working untouched. What did move is the runtime state — the package cache is `/var/cache/dnf`, not `/var/cache/yum`, and dnf logs to `/var/log/dnf.log`. The alias exists so that years of runbooks, kickstart files and playbooks keep running; it is not a promise that behaviour is identical.

code

bash · 3 lines
bash
ls -l /usr/bin/yum /usr/bin/dnf /etc/yum.conf
yum --version | head -1
ls /etc/yum.repos.d/

go deeper

for a junior

Know that on RHEL 8 and 9 typing yum runs dnf, and that repository files still live in /etc/yum.repos.d. Being able to say "follow the symlink" is most of the answer.

for a middle

Explain the mechanism: /usr/bin/yum and /usr/bin/dnf both point at dnf-3, /etc/yum.conf is a symlink to /etc/dnf/dnf.conf, and the cache and logs moved even though the config did not.

for a senior

Show where the compatibility ends — plugins, the removed Python API, and behaviour differences under RHEL's stricter shipped defaults — and describe how you would audit a fleet's automation for scripts that still import yum.

for a principal

Frame it as a deprecation strategy: an alias plus unchanged config paths bought a decade of runbooks a free migration, at the cost of hiding a semantic change behind an identical command name. Weigh that against a hard cutover when planning your own tool deprecations.

## What is actually at /usr/bin/yum On Red Hat Enterprise Linux 8 and 9 — and equally on CentOS Stream, AlmaLinux and Rocky Linux of those generations — `yum` is not a program of its own. It is a symbolic link: ```bash $ ls -l /usr/bin/yum /usr/bin/dnf lrwxrwxrwx. 1 root root 5 /usr/bin/yum -> dnf-3 lrwxrwxrwx. 1 root root 5 /usr/bin/dnf -> dnf-3 ``` Both names resolve to `dnf-3`, the Python 3 entry point of dnf. So `yum install httpd` and `dnf install httpd` are the same process doing the same work; there is no translation layer, no wrapper script, and no second dependency solver installed alongside. The link is shipped by a small `yum` compatibility package that simply requires dnf. ## Why the alias exists Red Hat replaced yum 3 with dnf in RHEL 8 because yum 3 was a Python 2 codebase with a dependency solver that had reached the end of its useful life; dnf uses libsolv for depsolving and hawkey/librepo underneath. But an operating system with a ten-year support life inherits a decade of muscle memory: shell history, wiki runbooks, kickstart `%post` sections, Chef recipes, Dockerfiles, and Ansible tasks that all say `yum`. Keeping the name working is the cheapest possible migration path for all of that. ## The configuration followed the command The compatibility is deliberately not limited to the command name. - `/etc/yum.conf` is a symlink to `/etc/dnf/dnf.conf`. Editing either edits the same file, so an old instruction that says "set `installonly_limit` in /etc/yum.conf" still lands in the right place. - Repository definitions did not move at all. dnf's default `reposdir` is `/etc/yum.repos.d`, so every existing `.repo` file — with its `[repoid]`, `name=`, `baseurl=` or `mirrorlist=`, `gpgcheck=` and `enabled=` keys — is read as-is. This is the single biggest reason the migration was tolerable: repository configuration, the part that is most customised per site, needed no change. - Variables such as `$releasever` and `$basearch` in those files are still expanded. What did move is runtime state, and this catches people who go looking for it: - the metadata and package cache is `/var/cache/dnf`, so `du -sh /var/cache/yum` on RHEL 8 usually reports an empty or absent directory; - transaction logging goes to `/var/log/dnf.log` rather than `/var/log/yum.log`. ## The helper commands were aliased too The old `yum-utils` family was reimplemented as dnf plugins. On RHEL 8 and 9 the `yum-utils` package is a compatibility shim that pulls in `dnf-utils` and `dnf-plugins-core`, which provide `yum-config-manager`, `yumdownloader` and `repoquery` as front ends for `dnf config-manager`, `dnf download` and `dnf repoquery`. So `yum-config-manager --add-repo <url>` still writes a `.repo` file into `/etc/yum.repos.d`, just by a different implementation. ## Where the compatibility stops The alias covers names and configuration, not internals or semantics. - **Plugins.** yum 3's plugin API is gone. A third-party plugin written for yum 3 (Python 2, dropped into yum's plugin directory) will not load; dnf plugins are separate packages against a different API. - **The Python API.** `import yum` no longer exists. Anything that drove package management by importing yum's library — including old automation and monitoring scripts — must be ported to `python3-dnf`. This is why the Ansible `yum` module needs the dnf Python bindings on RHEL 8+, and why `ansible.builtin.dnf` is now the module you should be writing. - **Behaviour.** Several everyday invocations resolve differently under dnf than they did under yum 3, because RHEL's shipped `dnf.conf` sets stricter defaults. That is a separate discussion, but it is the reason "yum still works" should never be read as "yum still behaves identically". ## Where genuinely old yum still lives Real yum 3 — version 3.4.3, running on Python 2.7 — is what RHEL 7 and CentOS Linux 7 shipped. Those are the boxes where `yum` is the actual resolver rather than an alias, and they are also the ones most likely to be out of support: CentOS Linux 7 reached end of life on 30 June 2024, and RHEL 7 left maintenance support on the same date with only paid extended support beyond it. If you meet a machine where `ls -l /usr/bin/yum` shows a real ELF binary rather than a symlink, you are on that generation, and everything about the box — not just its package manager — deserves a second look. ## What to say in an interview Lead with the symlink, name `dnf-3`, and mention that the repository directory did not change. Then add the caveat that identical command names do not imply identical outcomes. That order shows you have both read the man page and been bitten by it.

  • If yum and dnf are the same binary, what breaks when you copy an old yum plugin onto a RHEL 9 box?
    It simply never loads. yum 3's plugin API and its Python 2 plugin directory no longer exist; dnf plugins are separate RPMs written against dnf's own API and installed under the dnf plugin path. The same applies to any script that did `import yum` — there is no such module, only `python3-dnf`.
  • An old monitoring script parses /var/log/yum.log to report what was installed. What do you tell its owner on RHEL 8?
    That file is no longer written. dnf logs transactions to `/var/log/dnf.log`, with RPM-level detail in the companion dnf logs. Rather than reparse a log, point the script at `dnf history` or query the RPM database directly, both of which are stable interfaces where a log format is not.
  • How do you tell at a glance whether a RHEL-family box you have just logged into is a real-yum machine or a dnf machine?
    `ls -l /usr/bin/yum`. A symlink to `dnf-3` means RHEL 8 or 9; a real binary means RHEL/CentOS 7 with yum 3. `cat /etc/redhat-release` confirms it, and `rpm -q yum dnf` tells you which packages are actually installed.

saying these in an interview costs you the question

  • Claims yum and dnf are two separate resolvers on RHEL 9
  • Says repository files had to be moved to /etc/dnf/repos.d
  • Thinks yum is a shell alias rather than a symlinked binary
  • Assumes identical command name means identical behaviour
  • Looks for the package cache in /var/cache/yum on RHEL 8

context