I recently discovered this rescue feature and found it brilliant.
However, I was unable to make it work.
Even the official example fails to execute.
Maybe there is something in my settings which is incompatible.
# ansible --version
ansible [core 2.21.3]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /opt/ansible/venv/lib/python3.14/site-packages/ansible
ansible collection location = /opt
executable location = /opt/ansible/venv/bin/ansible
python version = 3.14.4 (main, Apr 8 2026, 04:02:31) [GCC 15.2.0] (/opt/ansible/venv/bin/python3.14)
jinja version = 3.1.6
pyyaml version = 6.0.3 (with libyaml v0.2.5)
# ansible-config dump --only-changed
CACHE_PLUGIN(/etc/ansible/ansible.cfg) = redis
CACHE_PLUGIN_CONNECTION(/etc/ansible/ansible.cfg) = tls://localhost:<port>:0:<password>
CACHE_PLUGIN_TIMEOUT(/etc/ansible/ansible.cfg) = 259200
CALLBACKS_ENABLED(/etc/ansible/ansible.cfg) = ['ansible.posix.profile_tasks']
COLLECTIONS_PATHS(/etc/ansible/ansible.cfg) = ['/opt']
CONFIG_FILE() = /etc/ansible/ansible.cfg
DEFAULT_DEBUG(/etc/ansible/ansible.cfg) = False
DEFAULT_EXECUTABLE(/etc/ansible/ansible.cfg) = /bin/bash
DEFAULT_FORKS(/etc/ansible/ansible.cfg) = 1000
DEFAULT_GATHERING(/etc/ansible/ansible.cfg) = explicit
DEFAULT_HASH_BEHAVIOUR(/etc/ansible/ansible.cfg) = replace
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = ['/etc/ansible/hosts']
DEFAULT_LOAD_CALLBACK_PLUGINS(/etc/ansible/ansible.cfg) = True
DEFAULT_LOG_PATH(/etc/ansible/ansible.cfg) = /var/log/ansible.log
DEFAULT_PRIVATE_ROLE_VARS(/etc/ansible/ansible.cfg) = False
DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/roles']
DEFAULT_TIMEOUT(/etc/ansible/ansible.cfg) = 240
DEFAULT_TRANSPORT(/etc/ansible/ansible.cfg) = ssh
DISPLAY_ARGS_TO_STDOUT(/etc/ansible/ansible.cfg) = False
EDITOR(env: EDITOR) = /usr/bin/gedit
ENABLE_TASK_DEBUGGER(/etc/ansible/ansible.cfg) = True
GALAXY_SERVER_LIST(/etc/ansible/ansible.cfg) = ['release_galaxy', 'test_galaxy', 'local_https', 'local_ssh', 'local_file', 'automation_hub']
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = True
INJECT_FACTS_AS_VARS(/etc/ansible/ansible.cfg) = True
INTERPRETER_PYTHON(/etc/ansible/ansible.cfg) = /usr/bin/python3
INVENTORY_ENABLED(/etc/ansible/ansible.cfg) = ['ini', 'script', 'auto', 'yaml']
PERSISTENT_COMMAND_TIMEOUT(/etc/ansible/ansible.cfg) = 3599
PERSISTENT_CONNECT_RETRY_TIMEOUT(/etc/ansible/ansible.cfg) = 300
PERSISTENT_CONNECT_TIMEOUT(/etc/ansible/ansible.cfg) = 3600
RETRY_FILES_ENABLED(/etc/ansible/ansible.cfg) = False
SHOW_CUSTOM_STATS(/etc/ansible/ansible.cfg) = True
GALAXY_SERVERS:
release_galaxy
==============
token(/etc/ansible/ansible.cfg) = <token>
url(/etc/ansible/ansible.cfg) = https://galaxy.ansible.com/
test_galaxy
===========
token(/etc/ansible/ansible.cfg) = <token>
url(/etc/ansible/ansible.cfg) = https://galaxy-dev.ansible.com/
local_https
===========
token(/etc/ansible/ansible.cfg) =
url(/etc/ansible/ansible.cfg) = git+https://local.example.com/
local_ssh
=========
token(/etc/ansible/ansible.cfg) =
url(/etc/ansible/ansible.cfg) = admin@local.example.com/
local_file
==========
token(/etc/ansible/ansible.cfg) =
url(/etc/ansible/ansible.cfg) = git+file:///path/to/file
automation_hub
==============
auth_url(/etc/ansible/ansible.cfg) = https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
token(/etc/ansible/ansible.cfg) = my_ah_token
url(/etc/ansible/ansible.cfg) = https://cloud.redhat.com/api/automation-hub/
Play:
- name: Rescueing a failed task
hosts: all
strategy: debug
tasks:
- name: Attempt and graceful roll back demo
block:
- name: Print a message
ansible.builtin.debug:
msg: 'I execute normally'
- name: Force a failure
ansible.builtin.command: /bin/false
- name: Never print this
ansible.builtin.debug:
msg: 'I never execute, due to the above task failing, :-('
rescue:
- name: Print when errors
ansible.builtin.debug:
msg: 'I caught an error'
- name: Force a failure in middle of recovery! >:-)
ansible.builtin.command: /bin/false
- name: Never print this
ansible.builtin.debug:
msg: 'I also never execute :-('
always:
- name: Always do this
ansible.builtin.debug:
msg: "This always executes"
The rescue and always sub-blocks are not executed despite the failed task:
ansible-playbook [core 2.21.3]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /opt/ansible/venv/lib/python3.14/site-packages/ansible
ansible collection location = /opt
executable location = /opt/ansible/venv/bin/ansible-playbook
python version = 3.14.4 (main, Apr 8 2026, 04:02:31) [GCC 15.2.0] (/opt/ansible/venv/bin/python3)
jinja version = 3.1.6
pyyaml version = 6.0.3 (with libyaml v0.2.5)
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
Loading collection ansible.builtin from
Set default localhost to localhost
Parsed /hosts inventory source with ini plugin
redirecting (type: cache) ansible.builtin.redis to community.general.redis
Loading collection community.general from /opt/ansible_collections/community/general
Redis connection: <redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.SSLConnection(db=0,username=<REDACTED>,password=<REDACTED>,socket_timeout=5,socket_read_size=32768,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7702bf96e710>,health_check_interval=0,client_name=None,driver_info=DriverInfo(name='redis-py', lib_version='8.1.0', _upstream=[]),redis_connect_func=None,credential_provider=<REDACTED>,protocol=None,legacy_responses=True,host=localhost,port=6380,socket_connect_timeout=5,socket_keepalive=True,socket_keepalive_options=<object object at 0x7702be45ce70>,ssl_keyfile=None,ssl_certfile=None,ssl_cert_reqs=required,ssl_include_verify_flags=None,ssl_exclude_verify_flags=None,ssl_ca_certs=None,ssl_ca_data=None,ssl_check_hostname=True,ssl_password=<REDACTED>,ssl_ca_path=None,ssl_validate_ocsp_stapled=False,ssl_validate_ocsp=False,ssl_ocsp_context=None,ssl_ocsp_expected_cert=None,ssl_min_version=None,ssl_ciphers=None,maint_notifications_pool_handler=<redis.maint_notifications.MaintNotificationsPoolHandler object at 0x7702bd424410>,maint_notifications_config=MaintNotificationsConfig(enabled=auto, proactive_reconnect=True, relaxed_timeout=10, endpoint_type=None),orig_host_address=localhost,orig_socket_timeout=5,orig_socket_connect_timeout=5)>)>)>
Loading callback plugin default of type stdout, v2.0 from /opt/ansible/venv/lib/python3.14/site-packages/ansible/plugins/callback/default.py
Loading collection ansible.posix from /opt/ansible_collections/ansible/posix
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
Loading callback plugin ansible.posix.profile_tasks of type aggregate, v2.0 from /opt/ansible_collections/ansible/posix/plugins/callback/profile_tasks.py
PLAYBOOK: rescue.yml **********************************************************************************************************************************************************************************************
Positional arguments: issues/rescue.yml
verbosity: 4
connection: ssh
become_method: sudo
tags: ('all',)
inventory: ('/hosts',)
subset: localhost
forks: 1000
1 plays in issues/rescue.yml
PLAY [Rescueing a failed task] ************************************************************************************************************************************************************************************
TASK [Print a message] ********************************************************************************************************************************************************************************************
task path: /playbooks/issues/rescue.yml:8
Wednesday 12 August 2026 14:47:30 +0200 (0:00:00.056) 0:00:00.056 ******
ok: [localhost] =>
msg: I execute normally
TASK [Force a failure] ********************************************************************************************************************************************************************************************
task path: /playbooks/issues/rescue.yml:12
Wednesday 12 August 2026 14:47:30 +0200 (0:00:00.023) 0:00:00.080 ******
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/bash -c 'echo ~root'
<localhost> EXEC /bin/bash -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099 `" && echo ansible-tmp-1786538850.7118332-1510574-167632767667099="` echo /root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099 `" )'
Using module file /opt/ansible/venv/lib/python3.14/site-packages/ansible/modules/command.py
<localhost> PUT /root/.ansible/tmp/ansible-local-15104620xuk8aw6/tmp25hx1tyx TO /root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099/AnsiballZ_command.py
<localhost> EXEC /bin/bash -c 'chmod u+rwx /root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099/ /root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099/AnsiballZ_command.py'
<localhost> EXEC /bin/bash -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099/AnsiballZ_command.py'
<localhost> EXEC /bin/bash -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099/ > /dev/null 2>&1'
[ERROR]: Task failed: Module failed: The command exited with a non-zero return code.
Origin: /playbooks/issues/rescue.yml:12:10
10 msg: 'I execute normally'
11
12 - name: Force a failure
^ column 10
Traceback (most recent call last):
File "/root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099/AnsiballZ_command.py", line 266, in <module>
_ansiballz_main(
File "/root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099/AnsiballZ_command.py", line 260, in _ansiballz_main
invoke_module(zipped_mod, encoded_params)
File "/root/.ansible/tmp/ansible-tmp-1786538850.7118332-1510574-167632767667099/AnsiballZ_command.py", line 140, in invoke_module
_loader.run_module(
File "/tmp/ansible_ansible.legacy.command_payload_exnf_f3h/ansible_ansible.legacy.command_payload.zip/ansible/module_utils/_internal/_ansiballz/_loader.py", line 35, in run_module
_run_module(
File "/tmp/ansible_ansible.legacy.command_payload_exnf_f3h/ansible_ansible.legacy.command_payload.zip/ansible/module_utils/_internal/_ansiballz/_loader.py", line 62, in _run_module
runpy.run_module(mod_name=module_fqn, init_globals=init_globals, run_name='__main__', alter_sys=True)
File "<frozen runpy>", line 226, in run_module
File "<frozen runpy>", line 98, in _run_module_code
File "<frozen runpy>", line 88, in _run_code
File "/tmp/ansible_ansible.legacy.command_payload_exnf_f3h/ansible_ansible.legacy.command_payload.zip/ansible/modules/command.py", line 367, in <module>
main()
File "/tmp/ansible_ansible.legacy.command_payload_exnf_f3h/ansible_ansible.legacy.command_payload.zip/ansible/modules/command.py", line 361, in main
module.fail_json(**r)
Message: The command exited with a non-zero return code.
The above target exception was the direct cause of the following controller exception:
Traceback (most recent call last):
File "/opt/ansible/venv/lib/python3.14/site-packages/ansible/executor/task_executor.py", line 324, in _execute
utr.maybe_raise_on_result()
~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/opt/ansible/venv/lib/python3.14/site-packages/ansible/_internal/_task.py", line 1263, in maybe_raise_on_result
raise _captured.AnsibleResultCapturedError(self.exception.event, self)
ansible._internal._errors._captured.AnsibleResultCapturedError: Module failed: The command exited with a non-zero return code.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/opt/ansible/venv/lib/python3.14/site-packages/ansible/executor/task_executor.py", line 327, in _execute
raise AnsibleTaskError(obj=self._task.get_ds()) from ex
ansible.errors.AnsibleTaskError: Task failed: Module failed: The command exited with a non-zero return code.
fatal: [localhost]: FAILED! =>
changed: true
cmd:
- /bin/false
delta: '0:00:00.004427'
end: '2026-08-12 14:47:30.924890'
msg: The command exited with a non-zero return code.
rc: 1
start: '2026-08-12 14:47:30.920463'
stderr: ''
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
[localhost] TASK: Force a failure (debug)> User interrupted execution