Since the T9068 configd refactor, vyos-configd builds a ConfigManager at startup. init_components() walks all of configd-include.json and calls load_as_module() on every entry. There's no error handling. One missing file kills the daemon:
vyos-configd[2402]: File "/usr/libexec/vyos/services/vyos-configd", line 327, in <module> vyos-configd[2402]: config_manager = ConfigManager(cache_config=False) vyos-configd[2402]: File "/usr/lib/python3/dist-packages/vyos/configmanager.py", line 82, in init_components vyos-configd[2402]: module = load_as_module(name, path) vyos-configd[2402]: FileNotFoundError: [Errno 2] No such file or directory: '/usr/libexec/vyos/conf_mode/service_aws_glb.py' systemd[1]: vyos-configd.service: Start request repeated too quickly.
systemd retries 24 times, then gives up for good.
Cause
service_aws_glb.py moved into the separate vyos-1x-aws package in T7671. But generate-configd-include-json.py still lists everything in src/conf_mode/:
files = [f for f in os.listdir(conf_scripts) if os.path.isfile(f'{conf_scripts}/{f}')]
That list ships in the main vyos-1x package. It names a script that only exists if you installed the optional AWS package. Nothing loaded the list eagerly before T9068, so it didn't matter until now.
Reproduction
On any image with T9068 and without vyos-1x-aws:
$ dpkg -l | grep 1x-aws $ ls /usr/libexec/vyos/conf_mode/service_aws_glb.py ls: cannot access ...: No such file or directory $ grep -c aws_glb /usr/share/vyos/configd-include.json 1 $ systemctl is-active vyos-configd failed
Affected images
I checked four:
- rolling 2026.06.24: no T9068, configd fine
- rolling 2026.07.11 (e5e36dd48): no T9068, configd fine
- smoketest ISO 2026.07.20 (69039b470): has T9068, but vyos-1x-aws is installed, so configd fine
- our downstream build, post-T9068, no -aws: configd dead
No released rolling has shipped T9068 yet.
Smoketest images differ from released images
build_iso checks vyos-1x out to packages/vyos-1x and builds there. Every binary package lands in packages/, including vyos-1x-aws. Then build-vyos-image:713 does
local_packages = glob.glob('../packages/*.deb') for f in local_packages: shutil.copy(f, os.path.join(defaults.LOCAL_PACKAGES_PATH, ...))
LOCAL_PACKAGES_PATH is config/packages.chroot/, which live-build installs unconditionally. So the smoketest image always has vyos-1x-aws.
Released images resolve from vyos-base.list.chroot, which lists only vyos-1x and vyos-user-utils. Nothing depends on or recommends vyos-1x-aws, so it isn't installed.
Effect
A dead configd doesn't look like a failure. Config scripts still run, just standalone per commit instead of inside the daemon. What breaks is whatever relied on daemon-resident state.
We hit it through VPP. VPP stops releasing the NIC on commit rollback. The VPP smoketests deliberately commit an invalid config first. VPP's apply() binds the NIC to vfio-pci and creates a same-named tap. Only then does a later validation abort the commit. With configd alive, the rollback cleans up: vfio modules unloaded, Removing from iommu group 0, interface back on virtio-pci. Without it, nothing happens. eth1 stays on driver tun under devices/virtual/net/. The PCI device stays on vfio-pci. vpp.service stays active. Only a reboot recovers.
Every commit after that re-detects eth1 as the tap. pci_id comes back None. The allowlist check rejects it with
NIC used by "eth1" is not validated for VPP.
virtio is in SUPPORTED_PCI_IDS. The interface being inspected just isn't the NIC anymore.
Same VM spec (4 core, 8G, isolcpus=2-3, hugepages=1800), same test_vpp.py. The image with a live configd passes. The one without fails from test_02 on.
FRRender's long-lived instance from T6747 probably has the same exposure. Haven't tested it.