# \`!vault\` encrypted strings no longer decrypting through \`to\_yaml\` after 2.19 upgrade

**URL:** <https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321>\
**Category:** Get Help\
**Tags:** ansible-vault\
**Created:** [August 18, 2025, 8:21pm UTC](https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321 "2025-08-18T20:21:59Z")\
**Posts on this page:** 6\
**Page:** 2

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [September 1, 2025, 7:36pm UTC](https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321/21 "2025-09-01T19:36:09Z")

</div>

Thanks. That helps me understand the scope of the various issues.

I’m still surprised at the vault-preserving behavior of `to_yaml`. Apparently I’ve never used it to emit data containing vaulted strings.

Also, the notion that `to_yaml` would behave differently from `to_json` or `to_toml` or `to_whatever` doesn’t feel right. On the other hand, json doesn’t have a tagging mechanism like yaml, so…🤷

So `to_yaml` is a weird one-off. I’m settling on the opinion that there _is no correct default_ when `to_yaml`ing data containing vaulted strings. I could see a `tags.vaulted` parameter which could be either _unspecified_ or one of `['preserve', 'decrypt', 'obfuscate']`, then have it _fail_ when it’s unspecified and passed vaulted data. That would leave the door open to deal with other types of tags (“sensitive”, user-defined) down the road which might require other behaviors. (I’d really like an `obfuscate` option.) That scheme could be adopted by other filters, too. Alas, the “fail” part would be a breaking change, so it would have to be phased in carefully.

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [September 1, 2025, 8:22pm UTC](https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321/22 "2025-09-01T20:22:32Z")

</div>

I’ve hacked together a `community.general.to_yaml` and `community.general.to_nice_yaml` filter which do not preserve vaulted strings:

> <https://github.com/ansible-collections/community.general/pull/10784>
>
> \##### SUMMARY
> These filters produce "regular" YAML and do not preserve vaulted …strings, as opposed to \`ansible.builtin.to\_yaml\` and \`ansible.builtin.to\_nice\_yaml\`. See https://forum.ansible.com/t/44321 for some background.
> 
> \##### ISSUE TYPE
> \- Feature Pull Request
> 
> \##### COMPONENT NAME
> to\_nice\_yaml filter
> to\_yaml filter

They work with ansible-core \>= 2.16 (which community.general 11.x.y supports; probably also some older ansible-core versions should work).

The `obfuscate` option sounds interesting, I’ll take a look at that tomorrow. For ansible-core 2.19+ that should be trivial to implement since `transform_to_native_types` allows setting `redact=True`; for ansible-core 2.18 and before it’s also trivial since `_to_native_types` right now calls `value.data` to decrypt, but can in that case simply return `<redacted>` (the string that ansible-core 2.19+ returns if `redact=True`).

---

<div class="post-metadata">

**Author:** ![BrainStone](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/brainstone/32/1297_2.png) [@BrainStone](https://forum.ansible.com/u/BrainStone)\
**Post date:** [September 1, 2025, 9:20pm UTC](https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321/23 "2025-09-01T21:20:45Z")

</div>

The behavior changed for that filter. Doesn’t matter if the code itself didn’t change or not.

Prior to 2.19 piping a vault encrypted string into it, would render the decrypted string, now it renders a representation of said vault encrypted string.  
That is changed behavior. Doesn’t matter why that change in behavior occurs, it’s still a change.

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [September 2, 2025, 4:39am UTC](https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321/24 "2025-09-02T04:39:23Z")

</div>

Technically every bugfix is a breaking change, since it changes observable behavior.

---

<div class="post-metadata">

**Author:** ![flowerysong](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/flowerysong/32/2305_2.png) [@flowerysong](https://forum.ansible.com/u/flowerysong)\
**Post date:** [September 2, 2025, 2:47pm UTC](https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321/25 "2025-09-02T14:47:21Z")

</div>

> [@BrainStone](#):
>
> The behavior changed for that filter. Doesn’t matter if the code itself didn’t change or not.

The filter’s behaviour has not changed, the data you are feeding it has changed due to a bug being fixed.

This distinction _does_ matter, because if the filter had been changed in such a drastic way it would be reasonable to revert that change to avoid breaking people’s existing Ansible content. Instead the opposite is true: addressing your case by changing the filter’s behaviour would be a breaking change with security implications.

> [@BrainStone](#):
>
> Prior to 2.19 piping a vault encrypted string into it, would render the decrypted string, now it renders a representation of said vault encrypted string.

This is not true. Here’s a demonstration of the filter’s behaviour in 2.13 (the oldest version I can easily test in my environment, released in 2022):

```console
ezekielh@pandora testing $ cat test.j2
{{ ansible_version }}

{{ foo == "hello world" }}

{{ foo | to_yaml }}
ezekielh@pandora testing $ ansible-playbook test.yml

PLAY [localhost] ***************************************************************

TASK [template] ****************************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

ezekielh@pandora testing $ cat /var/tmp/testfile
{'string': '2.13.13.post0', 'full': '2.13.13.post0', 'major': 2, 'minor': 13, 'revision': 13}

True

!vault |
  $ANSIBLE_VAULT;1.1;AES256
  35623336363236303833623238316533363965316461353465613163626665313735333130626337
  3266353730373737343965336666393166393634306137610a386430336632656532656265393633
  37653832663833383230303435343566313936666136643836336139633965333734303061636332
  3234336633363365610a306533633362323232386163353466346231323765316333393232356230
  3063

```

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [September 2, 2025, 2:47pm UTC](https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321/26 "2025-09-02T14:47:50Z")

</div>

fwiw, there is an issue about this logged at [Inconsistent rendering of vaulted inline vs. file vaulted variables · Issue #85722 · ansible/ansible · GitHub](https://github.com/ansible/ansible/issues/85722)

We haven’t decided on what recommendation we will provide, or what theoretical change we may make to assist users here.

[Previous page](https://forum.ansible.com/t/vault-encrypted-strings-no-longer-decrypting-through-to-yaml-after-2-19-upgrade/44321.md?page=1)
