Introduction
HashiCorp Vault cannot be unsealed because the required unseal keys are lost, unavailable, or the threshold number of keys cannot be gathered. Vault remains sealed and cannot serve requests.
Symptoms
Unseal failure:
```bash $ vault operator unseal
Error unsealing: Error making API request.
URL: PUT https://vault:8200/v1/sys/unseal Code: 400. Errors:
* 'key' must be a valid unseal key ```
Sealed status:
```bash $ vault status
Sealed: true Seal Type: shamir Total Shares: 5 Threshold: 3 Unseal Progress: 0/3 ```
Key not found:
```bash $ vault operator unseal my-key
Error: invalid key ```
Common Causes
- 1.Keys lost - Unseal keys not stored securely
- 2.Key holders unavailable - Required quorum of key holders not present
- 3.Auto-unseal misconfigured - Cloud KMS/Transit auto-unseal failed
- 4.Keys corrupted - Stored keys are corrupted or incomplete
- 5.Wrong key version - Using old key after rekey
- 6.Storage corruption - Backend storage corrupted
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check Vault Status
```bash # Check vault status vault status
# Output shows: Sealed: true Seal Type: shamir Total Shares: 5 Threshold: 3 Unseal Progress: 0/3 Recovery Mode: false
# Check if using auto-unseal vault status -format=json | jq '.type'
# Check storage backend vault status -format=json | jq '.storage'
# Check vault logs journalctl -u vault -n 100
# Or: cat /var/log/vault/vault.log | tail -100 ```
Step 2: Verify Auto-Unseal Configuration
```bash # If using auto-unseal, check configuration cat /etc/vault.d/vault.hcl | grep -A 10 seal
# For AWS KMS auto-unseal: seal "awskms" { region = "us-east-1" kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/xxx" }
# For Transit auto-unseal: seal "transit" { address = "https://vault-primary:8200" token = "s.xxx" disable_remount = false key_name = "autounseal" }
# Check if auto-unseal key exists # For AWS KMS: aws kms describe-key --key-id xxx
# Check IAM permissions for vault aws kms decrypt --key-id xxx --ciphertext-blob fileb://sealed.txt
# For Azure Key Vault: az keyvault key show --vault-name myvault --name vault-key ```
Step 3: Use Recovery Keys (Vault 1.0+)
```bash # If recovery keys are available (for auto-unseal) vault operator unseal -recovery
# Enter recovery key Recovery Key (will be hidden):
# Generate OTP for recovery vault operator generate-root -recovery -init
# Output: OTP: xxx Nonce: yyy
# Use OTP to decode encrypted root token vault operator generate-root -recovery -otp=<otp> <encoded_token>
# Recover root token vault operator generate-root -recovery -decode=<encoded> -otp=<otp> ```
Step 4: Restore from Backup
```bash # If you have a backup of Vault storage
# Stop vault systemctl stop vault
# Backup current state (in case) cp -r /opt/vault/data /opt/vault/data.corrupted
# Restore from backup rm -rf /opt/vault/data/* cp -r /backup/vault/data/* /opt/vault/data/
# Or for raft storage: rm -rf /opt/vault/data/raft/* cp -r /backup/vault/raft/* /opt/vault/data/raft/
# Set correct permissions chown -R vault:vault /opt/vault/data chmod -R 750 /opt/vault/data
# Start vault systemctl start vault
# Unseal with original keys vault operator unseal ```
Step 5: Use Raft Peer Recovery
```bash # For Raft storage with remaining healthy nodes
# Check raft peers vault operator raft list-peers
# Remove failed node vault operator raft remove-peer vault-server-2
# On failed node, reset and rejoin: # Stop vault systemctl stop vault
# Remove local raft data rm -rf /opt/vault/data/raft/raft.db rm -rf /opt/vault/data/raft/snapshots/*
# Start vault systemctl start vault
# Join raft cluster vault operator raft join http://vault-server-1:8200
# Unseal vault operator unseal ```
Step 6: Rekey Vault with New Keys
```bash # If you have enough existing keys to rekey
# Initiate rekey vault operator rekey -init -key-shares=5 -key-threshold=3
# Output: Key shares: 5 Key threshold: 3 Nonce: xxx
# Provide existing unseal keys vault operator rekey -nonce=xxx
# Enter key 1: # Enter key 2: # Enter key 3:
# New keys will be generated # Store these securely!
# If using auto-unseal: vault operator rekey -init -target=backup -key-shares=1 -key-threshold=1 ```
Step 7: Handle HSM Seal Issues
```bash # For HSM-based seals
# Check HSM connectivity # For SoftHSM: pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -L
# Check HSM token pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --login --pin 1234 -t
# Verify HSM key exists pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --login --pin 1234 -O
# Check vault HSM configuration seal "pkcs11" { lib = "/usr/lib/softhsm/libsofthsm2.so" slot = "0" pin = "1234" key_label = "vault-hsm-key" }
# If HSM key lost, Vault cannot be unsealed # Must restore from backup ```
Step 8: Debug Storage Backend
```bash # For Consul storage consul kv get -base64 vault/core/seal
# Check consul connectivity consul members
# For raft storage ls -la /opt/vault/data/raft/
# Check raft logs sqlite3 /opt/vault/data/raft/raft.db ".tables"
# For file storage ls -la /opt/vault/data/file/
# Check storage permissions ls -la /opt/vault/data/ stat /opt/vault/data
# Test storage connectivity # For Consul: curl http://consul:8500/v1/kv/vault?keys ```
Step 9: Emergency Root Token Generation
```bash # If you have enough unseal keys but lost root token
# Generate new root token vault operator generate-root -init
# Output: OTP: xxx Nonce: yyy Number of remaining unseal keys: 3
# Provide unseal keys vault operator generate-root -nonce=yyy
# Enter key 1: # Enter key 2: # Enter key 3:
# Get encoded root token Encoded Token: xxx
# Decode with OTP vault operator generate-root -decode=xxx -otp=<otp>
# New root token: hvs.xxx ```
Step 10: Prevent Future Key Loss
```bash # Best practices for key management:
# 1. Store keys in multiple secure locations # - Password managers (1Password, Bitwarden) # - Hardware security modules # - Shamir secret sharing across key holders
# 2. Document key holders # Create a document listing: # - Who holds which keys # - How to contact key holders # - Escrow procedures
# 3. Regular key rotation vault operator rekey -init -key-shares=5 -key-threshold=3
# 4. Enable auto-unseal (recommended) # In vault.hcl: seal "awskms" { region = "us-east-1" kms_key_id = "arn:aws:kms:..." }
# 5. Regular backups # Backup vault storage backend regularly
# 6. Test recovery procedures # Periodically test key recovery and backup restoration ```
Vault Unseal Checklist
| Check | Command | Expected |
|---|---|---|
| Vault status | vault status | Shows seal type |
| Keys available | secure storage | Keys exist |
| Auto-unseal config | vault.hcl | Properly configured |
| KMS accessible | aws kms describe-key | Key exists |
| Storage backend | backend check | Healthy |
| Backup exists | backup location | Recent backup |
Verification
```bash # After resolving unseal issue
# 1. Check vault unsealed vault status // Sealed: false
# 2. Verify access vault secrets list // Lists secret engines
# 3. Test authentication vault login <root-token> // Login successful
# 4. Check audit log vault audit list // Audit devices listed
# 5. Verify data accessible vault kv get secret/test // Returns stored value
# 6. Check cluster health (if clustered) vault operator raft list-peers // All peers healthy ```
Prevention
To prevent Vault unseal failures when keys are unavailable, implement these proactive measures:
1. Configure Auto-Unseal
```hcl # Use cloud KMS for automatic unsealing # In vault.hcl: seal "awskms" { region = "us-east-1" kms_key_id = "arn:aws:kms:us-east-1:123456789:key/abcd1234" }
# For transit auto-unseal: seal "transit" { address = "https://vault-primary.example.com:8200" token = "s.xxxxxxxx" key_name = "autounseal" } ```
2. Implement Key Escrow
```bash # Store encrypted key shares with multiple custodians cat << 'EOF' > /usr/local/bin/vault_key_escrow.sh #!/bin/bash KEY_SHARE=$1 CUSTODIAN=$2
# Encrypt key share with custodian's public key gpg --encrypt --recipient $CUSTODIAN \ --output /secure/escrow/${CUSTODIAN}_key_share.gpg $KEY_SHARE
echo "$(date): Key share escrowed to $CUSTODIAN" >> /var/log/vault_escrow.log EOF
chmod +x /usr/local/bin/vault_key_escrow.sh ```
3. Set Up Monitoring
groups:
- name: vault-seal
rules:
- alert: VaultSealed
expr: vault_sealed == 1
for: 1m
labels:
severity: critical
annotations:
summary: "Vault instance {{ $labels.instance }} is sealed"Best Practices Checklist
- [ ] Configure auto-unseal with cloud KMS
- [ ] Distribute keys to multiple custodians
- [ ] Set up Vault HA cluster
- [ ] Monitor seal status with alerts
- [ ] Document key recovery procedures
- [ ] Test recovery procedure quarterly
Related Issues
- [Fix Vault Secret Rotation Failed](/articles/fix-vault-secret-rotation-failed)
- [Fix Vault Lease Not Renewed](/articles/fix-vault-lease-not-renewed)
- [Fix Vault HSM Connection Lost](/articles/fix-vault-seals-hsm-connection-lost)
Related Articles
- [WordPress troubleshooting: Fix S3 Configuration Error - Complete Tr](fix-s3-configuration-error)
- [WordPress troubleshooting: Fix RDS Configuration Error - Complete T](fix-rds-configuration-error)
- [Technical troubleshooting: Fix Certificate Based Client Authentication Mtls C](certificate-based-client-authentication-mtls-cert-cn-mismatch)
- [Fix Fix 8021x Clients Still Authenticating Against Old Policy Server After Migration Issue in Identity & Access](fix-8021x-clients-still-authenticating-against-old-policy-server-after-migration)
- [Fix Active Directory Account Lockout Policy Too Aggressive](fix-active-directory-account-lockout-policy-too-aggressive)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Vault Unseal Failed No Key", "description": "Troubleshoot Vault unseal failure without keys. Use recovery keys, restore from backup.", "url": "https://www.fixwikihub.com/fix-vault-unseal-failed-no-key", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-05T06:30:50.506Z", "dateModified": "2026-04-05T06:30:50.506Z" } </script>