Skip to content

Standby reports Sealed: false but rejects every request with "Vault is sealed" after seal reload fails during leadership acquisition #32158

Open

Description

@shunki-fujita

Describe the bug
If TriggerSealReload or migrateSeal fails right after a standby acquires the HA lock, waitForLeadership calls c.barrier.Seal() and returns (vault/ha.go). As a result:

  • c.sealed stays 0, so vault status and sys/health report the node as unsealed.
  • Every request fails with Vault is sealed.
  • The node never tries to become active again, and vault operator unseal does nothing. Only a restart recovers it.

Both steps read storage on every leadership acquisition, even with a Shamir seal, so a single transient storage error is enough. The other failure paths in the same loop release the lock and continue (or seal fully via Shutdown()). Only these two seal the barrier alone. The TriggerSealReload path came in #26098.

To Reproduce
Steps to reproduce the behavior (etcd RBAC simulates a read error for the standby):

  1. Start etcd with auth, and two Vault nodes vault-a/vault-b using the config below with users vaulta/vaultb (roles ra/rb, readwrite on /vault/). Init and unseal both.
  2. Block /vault/core/seal-gen-info for vault-b only:
   etcdctl role revoke-permission rb --prefix /vault/
   etcdctl role grant-permission rb readwrite /vault/ /vault/core/seal-gen-info
   etcdctl role grant-permission rb readwrite $'/vault/core/seal-gen-info\x01' /vault0
  1. Stop vault-a. vault-b logs:
   [INFO]  core: acquired lock, enabling active operation
   [ERROR] core: seal configuration reload error: error="error checking for stale seal generation info: failed to fetch seal generation info: etcdserver: permission denied"
   [WARN]  core: vault is sealed
  1. Restore the permission, then restart and unseal vault-a.
  2. See error: vault token lookup on vault-b returns 503 Vault is sealed, while vault status shows:
   Sealed                 false
   HA Enabled             true
   HA Cluster             n/a
   HA Mode                standby
   Active Node Address    <none>

Expected behavior
The node should release the lock and retry, like the other setup failures in the loop. If it must seal, it should seal fully so that Sealed reflects the real state.

Environment:

  • Vault Server Version (retrieve with vault status): 2.0.3 (same code on main)
  • Vault CLI Version (retrieve with vault version): Vault v2.0.3 ('7193f9a48ff6093ca61b3b627a8671e770428ba6'), built 2026-06-17T12:39:45Z
  • Server Operating System/Architecture: Linux amd64 (Docker)

Vault server configuration file(s):

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = true
}
api_addr      = "http://vault-b:8200"
cluster_addr  = "https://vault-b:8201"
disable_mlock = true
storage "etcd" {
  address    = "http://etcd:2379"
  etcd_api   = "v3"
  ha_enabled = "true"
  sync       = "false"
  username   = "vaultb"
  password   = "<redacted>"
}

Additional context
I have a fix with a regression test (retry on these errors, and Shutdown() only during a seal migration). I can open a PR.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions