Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for HashiCorp Vault By James Joyner IV · · 10 min read Last reviewed Jul 2026

Vault Error: 'error migrating data' Storage Migration or Upgrade Failure on Start

Quick answer

Fix Vault storage migration and upgrade failures: seal before migrating, write a correct migrate.hcl, clear or resume the migration lock, match seal types, and roll upgrades safely.

  • #vault
  • #secrets
  • #security-hardening
  • #troubleshooting
  • #errors
Free toolkit

Stuck on this HashiCorp Vault error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Exact Error Message

$ vault operator migrate -config=migrate.hcl
2026-07-19T09:14:02.771Z [INFO]  copying keys from source to destination
Error migrating: error migrating data: failed to write value to destination:
failed to persist storage entry: context deadline exceeded

On a node that starts against partially migrated or newer storage you may instead see:

Error initializing core: migration is in progress; please complete the migration
before starting Vault, or run 'vault operator migrate' with -start to resume

Error parsing Seal configuration: seal type 'shamir' does not match
seal type stored in the destination backend

What It Means

Vault’s storage backend holds every encrypted secret, lease, token, and policy. vault operator migrate performs an offline copy of that data from one backend to another — typically Consul or a filesystem backend into integrated Raft storage. It is a bulk key-by-key copy, not a live replication mechanism, and it requires exclusive ownership of both backends. To enforce that, Vault writes a migration marker into storage. Any Vault process that finds an incomplete marker refuses to start rather than serving from half-copied data.

Upgrade failures come from a related but distinct constraint: Vault’s storage schema is forward-only. Each release may upgrade on-disk structures during the first unseal, and there is no downgrade path — an older binary pointed at storage a newer binary has touched will fail to initialise its core. Combined with the requirement that HA clusters upgrade standbys before the active node, this makes upgrade order load-bearing. The seal type mismatch in the second message above is the third common trap: the destination backend records which seal protects the master key, so migrating from a Shamir-sealed source into a backend that already carries auto-unseal metadata (or the reverse) aborts before any data moves.

Common Causes

  • Vault was still running and unsealed when vault operator migrate was invoked, so the source kept changing under the copy.
  • A previous migration was interrupted, leaving the migration lock in place and blocking both start and re-run.
  • The migrate.hcl stanzas are wrong — a mistyped path, a missing node_id, or credentials that only work for one of the two backends.
  • The upgrade skipped intermediate versions instead of stepping through them and reading each upgrade guide.
  • The active node was upgraded before the standbys, so older peers could not follow the newer leader.
  • The destination backend records a different seal type than the running configuration declares.

Diagnostic Commands

Confirm nothing is still serving. Every Vault process must be stopped, or at minimum sealed, before a migration runs:

systemctl status vault
vault status | grep -E 'Sealed|HA Mode|Storage Type'

Validate the migration config before you trust it with production data. A parse error at this stage is far cheaper than one halfway through the copy:

cat migrate.hcl
vault operator migrate -config=migrate.hcl -dryrun

Inspect the source backend directly to confirm the data is where you think it is. For a Raft source, the node data directory should contain raft.db and a vault subdirectory:

ls -la /opt/vault/data
ls -la /opt/vault/data/raft
du -sh /opt/vault/data

Check that the destination has room and that the Vault user can write to it — context deadline exceeded on write is very often a disk, permissions, or network problem rather than a Vault one:

df -h /opt/vault/data-new
sudo -u vault touch /opt/vault/data-new/.probe && echo writable

Take a snapshot before you do anything else. If the cluster is currently healthy and unsealed, this is your rollback:

vault operator raft snapshot save /backup/vault-pre-upgrade.snap
ls -lh /backup/vault-pre-upgrade.snap

If the snapshot itself fails, resolve that first — see Vault error: Raft snapshot failed.

Finally, read the startup logs in full. The line above the failure usually names the exact key that could not be written:

journalctl -u vault --since "30 min ago" --no-pager | grep -iE "migrat|seal|storage|panic"

Step-by-Step Resolution

  1. Stop Vault everywhere and confirm it stays stopped. Migration against a live backend produces silent data loss, not an error:
sudo systemctl stop vault
pgrep -a vault || echo "no vault processes running"
  1. Write a correct migrate.hcl with exactly one storage_source and one storage_destination stanza. The stanza labels are the backend types, and both must be fully configured:
storage_source "consul" {
  address = "127.0.0.1:8500"
  path    = "vault/"
}

storage_destination "raft" {
  path    = "/opt/vault/data"
  node_id = "vault-0"
}

cluster_addr = "https://vault-0.example.com:8201"
  1. Run the migration and let it finish. On a large backend this can take a long time; run it under tmux or nohup so a dropped SSH session does not interrupt it:
sudo -u vault vault operator migrate -config=migrate.hcl 2>&1 | tee /var/log/vault-migrate.log
  1. If a previous attempt was interrupted, resume rather than restarting from scratch. The -start flag tells the migration to begin at a given key prefix, skipping what was already copied:
sudo -u vault vault operator migrate -config=migrate.hcl -start "logical/"

Only start over from the beginning against a freshly emptied destination — a partial copy layered under a full re-run leaves stale keys behind.

  1. Reconcile the seal type. The destination records the seal that protects the master key, so your vault.hcl must declare the same seal the data was encrypted under. Migrating between seal types is a separate operation from migrating storage:
storage "raft" {
  path    = "/opt/vault/data"
  node_id = "vault-0"
}

seal "awskms" {
  region     = "us-east-1"
  kms_key_id = "alias/vault-unseal"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_cert_file = "/etc/vault/tls/vault.crt"
  tls_key_file  = "/etc/vault/tls/vault.key"
}

If the new node cannot reach that KMS key, the failure surfaces as an unseal error instead — see Vault error: auto-unseal KMS access denied.

  1. For version upgrades on an HA cluster, upgrade standbys first, then step down the active node last. Never upgrade the active node while standbys are on the older binary:
# on each standby, one at a time
sudo systemctl stop vault
sudo dnf upgrade -y vault
sudo systemctl start vault
vault status | grep -E 'HA Mode|Version'

# only once every standby is healthy on the new version
vault operator step-down          # run against the current active node
sudo systemctl stop vault && sudo dnf upgrade -y vault && sudo systemctl start vault

Upgrade one minor version at a time and read the upgrade guide for each intermediate release — some releases carry storage or plugin changes that must be applied in sequence. Automated rolling upgrades driven by autopilot (Vault Enterprise) handle this ordering for you, but the same version-by-version rule applies.

  1. Verify before declaring success. Unseal, confirm the storage type, and read a known secret end to end:
vault status | grep -E 'Sealed|Storage Type|Version'
vault operator raft list-peers
vault kv get secret/app/prod/db

Prevention

  • Always take and verify a snapshot immediately before any migration or upgrade, and confirm it restores in a test cluster.
  • Rehearse the migration against a copy of production data so the runtime and failure modes are known in advance.
  • Upgrade one minor version at a time and read each release’s upgrade guide rather than jumping several versions.
  • Keep migrate.hcl in version control next to your vault.hcl so the source and destination stanzas are reviewable.
  • Never plan to downgrade — the storage schema is forward-only, so a rollback means restoring a snapshot to the old version.
  • Pin the Vault package version in configuration management so an unattended dnf upgrade cannot upgrade the active node first.
  • migration is in progress; please complete the migration before starting Vault — the migration lock is still set; resume or complete it.
  • failed to setup raft storage: node_id is required — the destination Raft stanza is incomplete.
  • Error initializing storage of type consul: dial tcp: connection refused — the source backend is unreachable, so nothing was copied.
  • failed to decrypt encrypted stored keys — the seal declared in config does not match the one the destination data was sealed with.

Frequently Asked Questions

Can I migrate while Vault is running? No. vault operator migrate requires exclusive access to both backends and copies data key by key; anything written to the source during the copy is silently lost. Stop every Vault process on every node first and confirm with pgrep.

How do I resume an interrupted migration? Re-run the same command with -start set to the key prefix where the log stopped. This skips already-copied keys instead of restarting a multi-hour copy. Only wipe the destination and start over if you are unsure what was written.

Can I downgrade if the new version misbehaves? Not by swapping the binary. Vault’s storage schema is forward-only, so an older binary will refuse to initialise against storage a newer one has upgraded. Rollback means restoring the pre-upgrade snapshot into a cluster running the old version.

Which node do I upgrade first in an HA cluster? Standbys first, one at a time, then vault operator step-down on the active node and upgrade it last. Autopilot automated upgrades (Vault Enterprise) orchestrate this for you. For more Vault operations fixes, see the Vault guides.

Free download · 368-page PDF

Fixed it? Get 500 HashiCorp Vault & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.