Your playbook fails with a vault decryption error, and you're staring at encrypted secrets you can't access. Vault is Ansible's way to protect sensitive data, but when decryption fails, your automation stops cold.
Understanding the Error
Vault decryption errors appear as:
ERROR! Attempting to decrypt but no vault password foundOr:
ERROR! Decryption failed (no vault id match) on /path/to/file.ymlOr:
fatal: [webserver01]: FAILED! => {"msg": "A vault password must be specified to decrypt /path/to/vault.yml"}Each points to different root causes.
Step 1: Verify Vault Password Is Correct
The most common cause is simply the wrong password:
# Test password against vault file
ansible-vault view group_vars/all/vault.yml --ask-vault-passIf this fails with Decryption failed, your password is wrong.
For vault IDs (multiple passwords):
# View with specific vault ID
ansible-vault view --vault-id prod@prompt group_vars/production/vault.ymlCheck which vault ID encrypted the file:
# Look at vault header
head -1 group_vars/production/vault.ymlOutput shows:
$ANSIBLE_VAULT;1.2;AES256;prodThe prod after AES256 is the vault ID. You need that password.
Step 2: Provide Password Correctly
Several ways to provide vault passwords:
Interactive prompt:
ansible-playbook site.yml --ask-vault-passPassword file:
```bash # Create password file (SECURE THIS!) echo "my_password" > ~/.vault_pass.txt chmod 600 ~/.vault_pass.txt
ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt ```
Environment variable:
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass.txt
ansible-playbook site.ymlFor multiple vault IDs:
ansible-playbook site.yml --vault-id prod@~/.vault_prod.txt --vault-id dev@~/.vault_dev.txtStep 3: Check Vault File Format
Vault files must have proper format. Check the header:
head -5 group_vars/all/vault.ymlValid vault file starts with:
$ANSIBLE_VAULT;1.2;AES256If you see anything else, the file isn't properly encrypted:
```yaml # NOT encrypted - plain YAML my_secret: value123
# Encrypted - starts with $ANSIBLE_VAULT $ANSIBLE_VAULT;1.2;AES256 34563456... ```
Encrypt plain files:
ansible-vault encrypt group_vars/all/secrets.ymlStep 4: Fix Corrupted Vault Files
Vault files can become corrupted. Check file integrity:
# Verify file can be decrypted
ansible-vault view secrets.yml --ask-vault-passIf view fails with format errors:
ERROR! Invalid vault format: ...The file may be corrupted. Attempt recovery:
```bash # Check if content is binary corrupted file secrets.yml
# Try editing to see if it opens ansible-vault edit secrets.yml --ask-vault-pass ```
If completely corrupted, you need to restore from backup or re-create secrets.
Step 5: Handle Multiple Vault Passwords
Modern Ansible supports multiple vault passwords with IDs:
# Encrypt with specific ID
ansible-vault encrypt --vault-id prod@prompt secrets.ymlThe file header shows the ID:
$ANSIBLE_VAULT;1.2;AES256;prodTo decrypt, provide the matching ID password:
ansible-vault view --vault-id prod@prompt secrets.ymlConfigure default vault IDs in ansible.cfg:
[defaults]
vault_id_match = True
vault_identity_list = prod@~/.vault_prod.txt,dev@~/.vault_dev.txtStep 6: Fix Password Script Issues
Instead of password files, you can use scripts:
```bash # Password script that outputs password cat > ~/.vault_pass.sh << 'EOF' #!/bin/bash echo "my_password" EOF chmod +x ~/.vault_pass.sh
ansible-playbook site.yml --vault-password-file ~/.vault_pass.sh ```
If script fails:
```bash # Test script directly ~/.vault_pass.sh
# Check script permissions ls -la ~/.vault_pass.sh ```
Common script issues:
- Not executable (
chmod +x) - Script has errors
- Script outputs extra whitespace
Step 7: Verify Ansible Vault Version Compatibility
Vault format versions can mismatch:
# Check Ansible version
ansible --versionAnsible 2.4+ uses vault format 1.2. Older files in format 1.1 still work.
If you have very old vault files, upgrade them:
ansible-vault rekey secrets.yml --ask-vault-passStep 8: Debug Vault Loading
See which vault files Ansible loads:
ANSIBLE_DEBUG=True ansible-playbook site.yml --ask-vault-pass 2>&1 | grep vaultOr use verbose mode:
ansible-playbook site.yml --ask-vault-pass -vvvLook for vault-related messages:
vault_files: ['/path/to/vault.yml']
vault_password_matched: TrueStep 9: Fix Embedded Vault Strings
Strings can be encrypted inline in YAML:
database_password: !vault |
$ANSIBLE_VAULT;1.2;AES256
34563456...These need vault password too. Check inline vault works:
# Test playbook with inline vault
ansible-playbook site.yml --ask-vault-pass --checkIf inline vault fails, re-encrypt the string:
# Encrypt inline string
ansible-vault encrypt_string 'my_password' --name 'db_password'Step 10: Handle Vault in Roles
Roles with vault files need password at playbook level:
- hosts: all
roles:
- role: app
# Role has vault files in defaults or varsRun playbook with vault password:
ansible-playbook site.yml --ask-vault-passOr put vault password in role-specific file:
# Roles might have their own vault
ansible-playbook site.yml --vault-id app@~/.vault_app.txtStep 11: Manage Password Files Securely
Password files need protection:
```bash # Secure permissions chmod 600 ~/.vault_pass.txt
# Never commit password files echo "*.vault_pass.txt" >> .gitignore ```
Better approach - use password scripts that retrieve from secure storage:
#!/bin/bash
# Get password from environment or secret manager
if [ -n "$VAULT_PASSWORD" ]; then
echo "$VAULT_PASSWORD"
else
# Prompt user
read -s -p "Vault password: " pass
echo "$pass"
fiStep 12: Reset Vault Password
If you need to change vault password:
ansible-vault rekey secrets.yml --ask-vault-passThis prompts for old password then new password.
For multiple files:
ansible-vault rekey group_vars/*/vault.yml --ask-vault-passQuick Verification
Test vault decryption works:
```bash # View vault content ansible-vault view secrets.yml --ask-vault-pass
# Edit vault content ansible-vault edit secrets.yml --ask-vault-pass
# Decrypt temporarily ansible-vault decrypt secrets.yml --ask-vault-pass ansible-vault encrypt secrets.yml # Re-encrypt after ```
Test playbook with vault:
ansible-playbook site.yml --ask-vault-pass --checkSuccess shows no vault errors:
``` PLAY [all] ***************
TASK [Gathering Facts] *********** ok: [webserver01] ```
Prevention Best Practices
- 1.Use vault IDs for multiple environments:
# ansible.cfg
[defaults]
vault_identity_list = prod@~/.vault/prod.txt,dev@~/.vault/dev.txt- 1.Never commit password files:
# .gitignore
.vault_pass*
*.vault_password
.vault/- 1.Use encrypted string for partial secrets:
# Encrypt only sensitive values
config:
app_name: myapp # Plain text
db_password: !vault | # Encrypted
$ANSIBLE_VAULT;1.2;AES256
...- 1.Rotate vault passwords regularly:
ansible-vault rekey secrets.yml --ask-vault-pass- 1.Backup unencrypted vault content securely:
# Decrypt and backup (securely!)
ansible-vault decrypt secrets.yml --ask-vault-pass
cp secrets.yml secrets.yml.backup
ansible-vault encrypt secrets.ymlVault decryption failures usually mean wrong password, missing password, or corrupted files. Use ansible-vault view to test decryption, verify vault IDs match, and always protect password files.