Introduction
Starting with ansible-core 2.20 (Ansible 14), the skipped_reason result key is deprecated in favor of skip_reason. If you see the warning The 'skipped_reason' value is deprecated, your callback plugins or custom code needs updating before this becomes an error in a future release.
The Warning
[DEPRECATION WARNING]: The 'skipped_reason' value is deprecated,
use 'skip_reason' instead. This feature will be removed in a future release.
This appears when:
- A callback plugin accesses
result._result['skipped_reason'] - Custom action plugins set
skipped_reasonin results - Third-party collections use the old key name
The Fix
Callback Plugins
# ❌ Old (deprecated)
class CallbackModule(CallbackBase):
def v2_runner_on_skipped(self, result):
reason = result._result.get('skipped_reason', '')
self._display.display(f"SKIPPED: {reason}")
# ✅ New (correct)
class CallbackModule(CallbackBase):
def v2_runner_on_skipped(self, result):
reason = result._result.get('skip_reason', '')
self._display.display(f"SKIPPED: {reason}")
Backward-Compatible Fix
# ✅ Works with both old and new Ansible versions
class CallbackModule(CallbackBase):
def v2_runner_on_skipped(self, result):
reason = result._result.get('skip_reason',
result._result.get('skipped_reason', ''))
self._display.display(f"SKIPPED: {reason}")
Action Plugins
# ❌ Old
return dict(
skipped=True,
skipped_reason="Host not in target group"
)
# ✅ New
return dict(
skipped=True,
skip_reason="Host not in target group"
)
Playbook Impact
Standard playbooks using when conditions are not affected — this is an internal API change for plugin developers. However, if you register results and check skipped_reason:
# ❌ May break in future
- name: Run conditional task
ansible.builtin.command: echo hello
when: inventory_hostname in group_names
register: result
- name: Show skip reason (old way)
ansible.builtin.debug:
msg: "{{ result.skipped_reason | default('') }}"
when: result.skipped | default(false)
# ✅ Future-proof
- name: Show skip reason (new way)
ansible.builtin.debug:
msg: "{{ result.skip_reason | default(result.skipped_reason | default('')) }}"
when: result.skipped | default(false)
Check Your Code
# Find uses of skipped_reason in your project
grep -r "skipped_reason" roles/ plugins/ callback_plugins/ 2>/dev/null
# Find in installed collections
grep -r "skipped_reason" ~/.ansible/collections/ 2>/dev/null
# Find in custom callback plugins
grep -r "skipped_reason" /usr/share/ansible/plugins/callback/ 2>/dev/null
Common Affected Components
| Component | Action |
|---|---|
| Custom callback plugins | Replace skipped_reason → skip_reason |
| Custom action plugins | Update return dict key |
| Third-party collections | Update collection or wait for fix |
Playbooks using register | Add fallback: skip_reason | default(skipped_reason) |
| ansible.cfg callback settings | No change needed |
Timeline
| Version | Behavior |
|---|---|
| ansible-core ≤2.19 | skipped_reason works, no warning |
| ansible-core 2.20 (Ansible 14 RC) | Warning displayed |
| ansible-core 2.21+ (future) | skipped_reason removed — error |
Troubleshooting
| Issue | Solution |
|---|---|
| Warning appears but no custom plugins | A collection's callback plugin uses it — update the collection |
| Warning in CI/CD output | Add grep -v "DEPRECATION WARNING" or fix the source |
| Can't find the source | Run with -vvv to see which plugin triggers it |
| Need to support both old and new | Use fallback pattern: get('skip_reason', get('skipped_reason')) |
Best Practices
- Fix now, not later — deprecations become errors in the next major
- Use the fallback pattern for backward compatibility
- Update collections —
ansible-galaxy collection install --upgrade - Test with Ansible 14 RC —
pip install ansible==14.0.0rc1 - Search your codebase —
grep -r skipped_reasoncatches everything
Conclusion
Replace skipped_reason with skip_reason in all callback plugins, action plugins, and playbook result checks. Use the fallback pattern (skip_reason | default(skipped_reason)) if you need to support multiple Ansible versions. Fix it now — this becomes a hard error in a future ansible-core release.