If you are running automation against Debian 13 (Trixie) or modern Armbian forks using Python 3.13, you might encounter a baffling error during simple Ansible tasks. Your plays or ad-hoc commands will execute successfully on the remote target, but right at the finish line, Ansible crashes with a generic failure:
Task failed: Module failed: maximum recursion depth exceeded
The most frustrating part? The directory is actually created, or the file is successfully copied. The task does the work, but Ansible fails to report a successful return status.
Here is a look at why this happens and how a simple boot configuration tweak can fix it.
The Symptoms
When running an ad-hoc command like creating a directory or copying a file, you see a stack trace ending in an infinite loop:
ender3d.example.com | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3.13"
},
"changed": false,
"msg": "Task failed: Module failed: maximum recursion depth exceeded"
}
If you check the target machine, the file or directory exists.
The Root Cause: Missing Environment Context
Python 3.13 introduced stricter handling of user environment resolution. When Ansible connects via non-interactive SSH and escalates privileges via sudo, Python attempts to verify the executing user. If the environment variables USER and HOME are missing from the execution shell, an internal fallback loop in Python’s getpass.getuser() routine triggers an infinite recursion loop, crashing the engine before it can send a success signal back to your Ansible controller.
But why are USER and HOME missing in the first place?
The real culprit isn’t Python or Ansible—it is a silent conflict between the Linux kernel, D-Bus, and systemd-logind.
Many Armbian and Debian-derived kernel builds ship with SELinux hooks compiled and enabled at the kernel level by default. However, user-space SELinux tools are typically not installed on these distributions.
When Ansible establishes an SSH connection and triggers privilege escalation, systemd-logind attempts to instantiate a clean user session slice. Because the kernel indicates that SELinux is active, dbus-daemon and logind attempt to query the security context of your user. Because user-space SELinux utilities do not exist to resolve the query, D-Bus throws silent access errors and connection terminations. This underlying failure starves the newly spawned user session slice, preventing basic environment variables like USER and HOME from populating.
How to Diagnose the Issue
Before applying a fix, you can verify if this specific D-Bus and session starvation issue is happening on your machine. Run these commands on the target host:
- Check the System Log for D-Bus Errors:
Look for unknown security class errors or connection terminations from the D-Bus daemon:sudo journalctl -b | grep -E "dbus-daemon.*Unknown class|connection terminated"
If you see messages like “Unknown class dbus” or systemd services abruptly dropping their D-Bus connections, your system is hitting this exact friction point.
- Verify Environment Starvation in Non-Interactive Shells:
Simulate how Ansible logs in by running a non-interactive SSH command from your local machine to check if USER or HOME are empty:ssh user@your-target-ip "env | grep -E 'USER|HOME'"
If this returns blank or is missing critical paths despite a successful SSH connection, your session initialization is being blocked.
The Resolution
To fix this, you must explicitly tell the kernel to completely disable SELinux hooks. This prevents D-Bus from making the phantom security context lookups, allowing systemd to initialize sessions normally.
- Open the Armbian environment boot configuration file on the target machine:
sudo nano /boot/armbianEnv.txt - Append or modify the extraargs line to include selinux=0:
extraargs=selinux=0 - Save the file and reboot the system:
sudo reboot
Once the system comes back online, D-Bus will skip the context lookups, your non-interactive SSH sessions will populate with the correct environment variables, and your Ansible playbooks and ad-hoc commands will return a clean, green success status.