Ansible task fails with 'sudo: a terminal is required' when running over SSH without a TTY

2026-11-14 · 2 min read

Ansible task fails with "sudo: a terminal is required" when running over SSH without a TTY

Your playbook dies halfway through a deploy at the first become: true task. The remote host returns:


sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper

You now have a partially configured host, a failed CI run, and a rerun that will hit the same task. The ansible sudo a terminal is required failure is usually a transport and privilege-escalation mismatch, not a broken sudoers file.

Why "ansible sudo a terminal is required" appears over SSH

Ansible opens SSH sessions without a pseudo-terminal by default. sudo expects a terminal when it needs to prompt for a password. Without one, sudo cannot read the password and exits before running your command. [link needed]

The same message appears when a command or shell task calls sudo directly and omits -S. In that case Ansible is not managing the password prompt at all. Run the failing play with -vvv and inspect the exact remote command. If the line is /usr/bin/sudo -H -n ..., sudo is being forced non-interactive. If it is plain sudo ..., no stdin flag was passed.

Fix it with this procedure

1. Confirm where sudo is invoked. Run ansible-playbook -vvv ... and read the expanded command. If the task contains command: sudo ..., fix the task first; otherwise change the become configuration.

2. For Ansible-driven escalation, set become: true, become_method: sudo, and become_flags: -S. Use -S -n only when passwordless sudo is expected. -S tells sudo to read the password from stdin. [link needed]

3. Supply the password source: --ask-become-pass, a vaulted ansible_become_password, or an ansible_become_pass variable scoped to the host or group.

4. If you cannot pass a password, add a narrow sudoers rule with NOPASSWD for the automation user or exact commands. Validate with visudo -c.

5. If sudoers sets Defaults requiretty, allocate a TTY for that connection, for example ansible_ssh_common_args: '-tt' on the host or group. Keep it scoped. This is the other valid end of the ansible sudo a terminal is required fix; do not mix it with passwordless rules unless you need both.

6. Re-run one failing task with --start-at-task or a tag before running the whole play. The -vvv sudo line should now contain -S or a TTY should be present.

When NOT to do this

Do not add -tt globally by habit. A TTY can merge stdout and stderr and change line endings, which breaks tasks that parse command output. [link needed]

Do not add blanket NOPASSWD: ALL unless the automation account is already treated as root-equivalent. Prefer command-scoped rules.

Do not set become_flags: -S without a password source. -S still needs bytes on stdin, so pair it with --ask-become-pass, ansible_become_password, or -n for NOPASSWD.

Checklist