On a RHEL 8 host, `dnf install nodejs` installs Node.js 10 but your application needs Node.js 20. Walk through how you inspect and switch the module stream with dnf, and explain why `dnf module reset` is usually part of it.
answer
- one stream at a time
- the default stream is old on purpose
- reset before enable
- installed packages do not move themselves
- distro-sync, or switch-to
basics
~20 sRHEL 8 ships several runtime versions as module streams, and one is marked default. Inspect with dnf module list nodejs, then reset the module's stream selection, enable the stream you want, and sync the installed packages onto it — dnf module switch-to does all three.
solid answer
~50 sRHEL 8 packages some runtimes as modules, each offering several *streams* — parallel versions of the same content — with one marked as the distribution default, which is why a plain install lands on an old Node.js. I'd start with `dnf module list nodejs` to see the available streams and the markers for default, enabled and installed, and `dnf module info nodejs:20` for its profiles. Only one stream of a module can be enabled at a time, so switching means clearing the current selection first: `dnf module reset nodejs`, then `dnf module enable nodejs:20`. Reset does not touch installed packages, so the final and easily forgotten step is `dnf distro-sync nodejs npm` to move the already-installed packages onto the new stream's versions. Newer dnf 4 releases fold all of that into `dnf module switch-to nodejs:20`. Afterwards I'd verify with `dnf module list --enabled` and the runtime's own version output.
code
bash · 11 lines# What streams exist, and which is default/enabled/installed?
dnf module list nodejs
dnf module info nodejs:20
# Clear the current choice, pick the new stream, reconcile packages
sudo dnf module reset nodejs
sudo dnf module enable nodejs:20
sudo dnf distro-sync nodejs npm
# Newer dnf 4 does all three in one transaction
sudo dnf module switch-to nodejs:20go deeper
Know that some RHEL 8 content ships as modules with multiple version streams, that one is the default, and that dnf module list <name> shows you which versions exist.
Explain the mechanics: one stream enabled at a time, what the default/enabled/installed markers mean, and the reset-then-enable sequence with the profiles a stream offers.
Show you have done it live — name the distro-sync step that reconciles already-installed packages, know dnf module switch-to folds the sequence into one transaction, and treat an EOL stream as a silent patching gap.
Own the fleet position: whether module state belongs in configuration management or in a baked image, how you audit enabled streams for support lifecycle, and when a container or a vendor repository is the better way to deliver a newer runtime.
## What a module is, from the command line On RHEL 8, some content — language runtimes, databases, some tools — is delivered as *modules* rather than as plain packages. A module is a named bundle of packages that comes in several **streams**: parallel versions of the same software, such as `nodejs:10`, `nodejs:18` and `nodejs:20`, built to coexist in the repository but not on the machine. Each stream offers one or more **profiles**, which are named package sets for a use case (a `common` profile for a normal runtime install, a `development` profile that adds headers, and so on). One stream per module is marked as the distribution default. That is why a plain `dnf install nodejs` on an untouched RHEL 8 host gives you the old runtime: the default stream is chosen for stability across the release, not to be current. ## Looking before you leap ```bash dnf module list nodejs # streams, profiles and their state dnf module info nodejs:20 # what this stream actually contains dnf module list --enabled # every module stream enabled on this host ``` `dnf module list` annotates each row with markers whose legend it prints: `[d]` default, `[e]` enabled, `[x]` disabled, `[i]` installed. Reading those four correctly is most of the skill. "Default" means what you get if you never make a choice; "enabled" means an explicit choice has been recorded; "installed" means packages from that stream are actually on the box. They are independent, and a host in a confusing state usually has them out of alignment. ## The switch, and why reset exists Only one stream of a given module can be enabled at a time — that is the core constraint the whole workflow follows from. dnf will not silently swap one enabled stream for another, because doing so would change the versions of installed packages behind your back. So the sequence is: ```bash sudo dnf module reset nodejs # forget the current stream selection sudo dnf module enable nodejs:20 # record the new one sudo dnf distro-sync nodejs npm # move installed packages onto it ``` `dnf module reset` returns the module to the state of having no explicit choice: neither enabled nor disabled. Critically, **it does not remove or downgrade anything already installed** — a point candidates get wrong constantly. After reset and enable, the packages on disk are still the ones from the old stream; they are simply now inconsistent with the enabled stream. `dnf distro-sync` is what reconciles them, moving each package to the version the enabled stream offers, upgrading or downgrading as needed. Skip it and you get the worst of both worlds: metadata that says 20, a binary that says 10, and an application that fails in a way nobody can explain. Newer dnf 4 releases add `dnf module switch-to nodejs:20`, which performs the reset, the enable and the distro-sync as one transaction. It is the command to prefer when it is available, precisely because it removes the step people forget. `dnf module install nodejs:20/common` is the other common form, installing a specific profile of a stream directly. `dnf module disable nodejs` is a third state, distinct from reset: it makes the module's content unavailable entirely, which is how you stop modular packages from shadowing something you install from another repository. ## The operational traps **Streams have their own lifecycle.** A stream can reach end of life while the underlying distribution release is still fully supported, at which point it silently stops receiving updates. A host sitting on an EOL stream looks patched — `dnf upgrade` reports nothing to do — while quietly receiving no fixes for that runtime. Checking which streams your fleet has enabled is a real audit task, not a curiosity. **Enabled state is host state.** It lives on the machine and is easy to drift between hosts that were built at different times. If you build hosts by hand, module state is one of the first things to diverge; expressing it in configuration management or baking it into the image is the durable answer. **Dependent modules.** Enabling one stream can require or conflict with a stream of another module, and the error you get names the conflict. Read it rather than reaching for a force flag. ## Where this is going Modularity is a mechanism you operate on existing RHEL 8 and 9 fleets, not one to build new architecture around — Fedora has wound it down. The interview value is unchanged: it is a very good probe for whether you have actually driven a runtime upgrade on a long-lived enterprise host, because the person who has will mention the distro-sync step unprompted, and the person who has only read about modules will stop at `enable`.
- What is the difference between `dnf module reset` and `dnf module disable`?Reset clears the recorded choice, returning the module to "no explicit selection" so the default applies again and another stream can be enabled. Disable goes further: the module's content becomes unavailable entirely, so its packages will not be offered at all. Disable is what you use to stop modular packages shadowing a version you install from a third-party repository. Neither one removes packages already installed.
- A team reports that `dnf upgrade` shows nothing to do for a runtime that has known CVEs. How could the module stream explain that?The host may have an end-of-life stream enabled. Streams carry their own support lifecycle, independent of the distribution release, and once a stream is retired it stops receiving updates while `dnf upgrade` still reports the system as current. `dnf module list --enabled` shows what is selected; the fix is switching to a supported stream and then running a distro-sync, not more upgrading.
saying these in an interview costs you the question
- Thinking several streams of one module can be enabled at once
- Believing `dnf module reset` downgrades installed packages
- Stopping after enable and skipping the distro-sync
- Assuming the default stream is the newest version
- Treating stream EOL as tied to the distribution release