Ansible published ansible-core v2.20.8 on 10 August 2026. The patch closes a hang in parallel fact gathering when async job files are corrupt, and it makes the async wrapper consult remaining timeout before it kills a module process. Operators who gather facts at inventory scale, and hosts that import RPM keys through rpm_key, are the audience for this tag.
The full release notes and downloads are on the GitHub release page. The v2.20.8 section of the changelog is the source for the items below.
Parallel fact gathering timeout and hang ¶
Fact collection is the first real I/O in many ETL and fleet playbooks. Parallel fact gathering wraps module processes in an async helper. Before this tag, that helper slept five seconds, slept five seconds again, then asked whether the job still had time. The kill decision did not track remaining timeout. A host that stalled inside setup or another fact module could sit past the budget while the wrapper waited on those fixed sleeps.
v2.20.8 changes that. The async wrapper now considers the timeout when it decides whether to kill the process running the module. Fact gather timeouts should fire closer to the configured deadline instead of after an extra ten seconds of sleep.
The same area had a hang from corrupt async job files. A truncated or garbage async status file could leave the gatherer waiting forever. That is a production failure mode after a crash, a full disk, or a controller process that was killed. The changelog records a fix for that hang. If a playbook has been stuck in Gathering Facts with no CPU and no SSH traffic, this tag is the first thing to test.
Winners are long inventory runs that use parallel facts. The cost is that a module that previously got an extra ten seconds of grace from the double sleep will now die on schedule. That is the intended contract.
rpm_key PGP armor and librpm ¶
rpm_key imports PGP armor into the RPM trust store. On some systems pgpParsePkts in librpm requires a trailing newline on the armor blob. Without it, the module failed even when the key file was otherwise valid.
The fix is small: ensure a trailing newline is present on PGP armor data before passing it to librpm. The changelog cites issue 87303. Playbooks that bootstrap repo keys for dnf or yum hosts, including package mirrors that feed data plane nodes, should stop failing on that parser requirement.
This is not a new key format. It is a parser quirk. If rpm_key already succeeds on a given distro, the change does nothing. If it fails with a parse error on armor that looks correct, this is the likely cause.
Collection loader and compiled extensions ¶
The collection loader now returns a Python module when pkgutil.iter_modules is called on a package that lives inside a collection path and contains compiled Python extension modules. That is a plugin discovery bug, not a playbook syntax change.
Collections that ship native extensions next to Python packages could disappear from iteration. ETL collections that wrap native parsers, compression, or crypto fall into that class. After the fix, pkgutil.iter_modules should list those modules instead of skipping the package.
If a collection contains only pure Python, this path does not matter. If a collection mixes extension modules and Python, recheck plugin load after the upgrade.
ansible-test timeout stacks and target filtering ¶
Three ansible-test items landed with this tag. They matter to people who run core integration tests as a CI gate for data platform playbooks.
A timeout callback dumps thread stacks when the test execution deadline from ansible-test env --timeout is approaching. That is diagnostic output for hung tests, not a new timeout policy. When a job hits the deadline, stacks should show which thread is stuck instead of a silent kill.
ansible-test also loads test collections automatically in core integration tests. That is plumbing for collection tests that ship with core. It reduces manual collection path setup in CI.
Target filtering now preserves user specified versions that are not in the completion configuration. Previously a version you passed that was missing from completion data could be dropped. That made it look like the test runner ignored an explicit target. The filter now keeps those versions.
These are CI internals. They do not change playbook runtime. They do change how hung ansible-test jobs are diagnosed and how you pin OS versions that the completion file does not list.
Where to get it ¶
- GitHub release page
- ansible/ansible repository
- Tag:
v2.20.8