Privilege escalation errors occur when Ansible cannot switch to a user with sufficient permissions to execute a task. Most commonly, this means the become directive is missing or misconfigured. This guide covers every common privilege escalation error and how to fix it.

How Privilege Escalation Works in Ansible

When you set become: true, Ansible:

  1. Connects to the target host as the connection user (e.g., deploy)
  2. Switches to the become user (default: root) using the become method (default: sudo)
  3. Executes the task with the elevated privileges
  4. Returns results to the connection user
Control Node → SSH as 'deploy' → sudo → root → Execute task

The Most Common Error

Missing become: true

Error:

fatal: [webserver]: FAILED! => {
    "msg": "This command has to be run under the root user.",
    "rc": 1
}

Or:

fatal: [webserver]: FAILED! => {
    "msg": "Permission denied"
}

Wrong — no privilege escalation:

---
- name: Install packages
  hosts: all
  become: false    # or become not specified at all
  tasks:
    - name: Install git
      ansible.builtin.yum:
        name: git
        state: present

Correct — become enabled:

---
- name: Install packages
  hosts: all
  become: true
  tasks:
    - name: Install git
      ansible.builtin.yum:
        name: git
        state: present

Where to Set become

Play Level (All Tasks in Play)

- name: System setup
  hosts: all
  become: true      # All tasks run as root
  tasks:
    - name: Install packages
      ansible.builtin.apt:
        name: nginx
        state: present

Task Level (Specific Tasks Only)

- name: Mixed privilege play
  hosts: all
  become: false
  tasks:
    - name: Check disk space (no root needed)
      ansible.builtin.command: df -h
      register: disk_info

    - name: Install package (needs root)
      ansible.builtin.apt:
        name: nginx
        state: present
      become: true    # Only this task escalates

Block Level

- name: Grouped escalation
  hosts: all
  tasks:
    - block:
        - name: Install nginx
          ansible.builtin.apt:
            name: nginx
            state: present

        - name: Start nginx
          ansible.builtin.service:
            name: nginx
            state: started
      become: true    # Both tasks in block escalate

In ansible.cfg

[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False

In Inventory

[webservers:vars]
ansible_become=true
ansible_become_method=sudo
ansible_become_user=root

Common Error Messages and Fixes

"sudo: a password is required"

fatal: [host]: FAILED! => {"msg": "Missing sudo password"}

Fix options:

  1. Pass password interactively:
ansible-playbook site.yml -K
  1. Configure passwordless sudo on the target:
# /etc/sudoers.d/deploy
deploy ALL=(ALL) NOPASSWD: ALL
  1. Use Ansible Vault:
# group_vars/all/vault.yml (encrypted)
ansible_become_password: "sudo_password"

"sudo: no tty present and no askpass program specified"

fatal: [host]: FAILED! => {"msg": "sudo: no tty present and no askpass program specified"}

Cause: The sudoers file requires a TTY for sudo.

Fix: Add to sudoers on the target:

Defaults:deploy !requiretty

Or in ansible.cfg:

[ssh_connection]
ssh_args = -o RequestTTY=yes

"User deploy is not allowed to execute"

fatal: [host]: FAILED! => {"msg": "Sorry, user deploy is not allowed to execute '/bin/yum' as root"}

Cause: The user's sudoers entry restricts which commands they can run.

Fix: Update sudoers to allow the needed commands:

deploy ALL=(ALL) NOPASSWD: /usr/bin/yum, /usr/bin/apt-get, /usr/bin/systemctl

Or allow all commands:

deploy ALL=(ALL) NOPASSWD: ALL

"become_user requires become"

ERROR! become_user requires become to be set to True

Fix: Add become: true alongside become_user:

- name: Run as postgres
  ansible.builtin.command: psql -c "SELECT 1"
  become: true
  become_user: postgres

Becoming a Non-Root User

Sometimes you need to run as a service account, not root:

- name: Run database migration
  ansible.builtin.command: python manage.py migrate
  become: true
  become_user: django
  args:
    chdir: /opt/myapp

- name: Check PostgreSQL status
  ansible.builtin.command: pg_isready
  become: true
  become_user: postgres

become_method Options

MethodUse Case
sudoDefault, most Linux systems
suSwitch user (needs target user's password)
pbrunPowerBroker
pfexecSolaris privilege exec
doasOpenBSD
dzdoCentrify
ksuKerberos
runasWindows (with ansible.builtin.runas)
machinectlsystemd-nspawn containers
enableNetwork devices (enable mode)
- name: Task on OpenBSD
  ansible.builtin.command: pkg_add nginx
  become: true
  become_method: doas

Debugging Privilege Escalation

Test sudo Manually

# SSH to the host
ssh deploy@webserver

# Test sudo
sudo -l           # List allowed commands
sudo whoami       # Should print "root"
sudo -u postgres whoami   # Should print "postgres"

Use Verbose Mode

ansible-playbook site.yml -vvv

Look for lines containing BECOME and sudo to see the exact escalation command.

Check become Works with ping

ansible webserver -m ping --become

Conclusion

Most Ansible privilege escalation errors come down to one missing line: become: true. For production environments, configure passwordless sudo for your Ansible service account and set become = True in ansible.cfg. For tasks requiring specific service accounts, combine become: true with become_user. Always test privilege escalation with ansible host -m ping --become before running full playbooks.