What's Actually Happening

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.

The Error You'll See

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 ```

Why This Happens

  1. 1.Keys lost - Unseal keys not stored securely
  2. 2.Key holders unavailable - Required quorum of key holders not present
  3. 3.Auto-unseal misconfigured - Cloud KMS/Transit auto-unseal failed
  4. 4.Keys corrupted - Stored keys are corrupted or incomplete
  5. 5.Wrong key version - Using old key after rekey
  6. 6.Storage corruption - Backend storage corrupted

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

CheckCommandExpected
Vault statusvault statusShows seal type
Keys availablesecure storageKeys exist
Auto-unseal configvault.hclProperly configured
KMS accessibleaws kms describe-keyKey exists
Storage backendbackend checkHealthy
Backup existsbackup locationRecent backup

Verify the Fix

```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 ```

  • [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)