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 · · 9 min read Last reviewed Jul 2026

Vault Error: 'request rate limit quota exceeded' HTTP 429 Throttling

Quick answer

Fix Vault's HTTP 429 'request rate limit quota exceeded': inspect sys/quotas/config, tune per-path and per-namespace rate-limit quotas, block_interval, and client retry/backoff.

  • #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

Error making API request.

URL: GET https://vault.example.com:8200/v1/secret/data/app/prod/db
Code: 429. Errors:

* request rate limit quota exceeded

Applications using an HTTP client rather than the CLI may instead see:

{"errors":["request rate limit quota exceeded"]}
HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-07-19T14:22:31Z

What It Means

Vault ships with a resource quota subsystem that throttles inbound API requests. A rate limit quota defines a maximum number of requests per interval, scoped either globally, to a namespace, to a mount, or to a specific path prefix. When the count of requests matching a quota exceeds rate within interval, Vault rejects further matching requests with HTTP 429 and the body request rate limit quota exceeded. The rejection happens in the HTTP handler before the request reaches the secrets engine, so it costs almost nothing on the server but tells you nothing about the underlying secret.

Quotas are evaluated most-specific-first: a quota on secret/data/app wins over one on secret/, which wins over the global default quota defined in sys/quotas/config. Only the single most specific matching quota applies — they do not stack. Rate limits are enforced per Vault node, not cluster-wide, so a three-node cluster behind a load balancer effectively permits roughly three times the configured rate unless traffic is pinned. If a quota also sets a non-zero block_interval, a client that trips the limit is blocked for that full duration rather than being allowed back in as soon as the interval rolls over — which is why a brief burst can produce a surprisingly long outage for one caller.

Common Causes

  • A global default rate limit quota is configured in sys/quotas/config and a legitimate traffic increase now exceeds it.
  • A narrow per-path quota (for example on a login endpoint) is far tighter than the team expects.
  • A client is not caching tokens or secrets and re-authenticates on every single request, multiplying request volume.
  • A deployment rollout or CI fan-out starts hundreds of pods simultaneously, all reading Vault at t=0.
  • block_interval is set, so one short burst blocks a caller for minutes rather than seconds.
  • A load balancer or API gateway in front of Vault is returning its own 429, and the error is not coming from Vault at all.

Diagnostic Commands

First confirm whether the 429 originated from Vault. A Vault-generated throttle always carries a JSON errors array; a proxy-generated one usually does not:

curl -i -H "X-Vault-Token: $VAULT_TOKEN" \
  https://vault.example.com:8200/v1/secret/data/app/prod/db

Look at the global quota configuration, which includes the default rate applied when no more specific quota matches:

vault read sys/quotas/config

List every rate limit quota defined on the cluster, then read the one you suspect:

vault list sys/quotas/rate-limit
vault read sys/quotas/rate-limit/global-default
vault read sys/quotas/rate-limit/kv-app-prod

The read output shows rate, interval, block_interval, path, role, and inheritable, which is enough to work out exactly which callers are affected.

Check the telemetry counter that increments on every rejection. If you scrape Prometheus from Vault, the violation metric is the fastest way to see which quota is firing:

curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
  "https://vault.example.com:8200/v1/sys/metrics?format=prometheus" \
  | grep -i vault_quota_rate_limit_violation

The equivalent internal metric name is vault.quota.rate_limit.violation, labelled with the quota name — graph it alongside request volume to see whether you are hitting a ceiling continuously or only during bursts.

If you cannot tell which client is responsible, enable rate limit audit logging temporarily so each rejection is written to the audit device, then read the audit log:

vault write sys/quotas/config enable_rate_limit_audit_logging=true
tail -f /var/log/vault/audit.log | grep -i "rate limit"

Turn this back off when you are done — it can be very noisy, and heavy audit volume creates its own problems, as covered in Vault error: audit device blocking.

Step-by-Step Resolution

  1. Confirm the source. If the response has no JSON body and no X-RateLimit-* headers, the throttle is coming from your load balancer or ingress, not Vault, and the fix belongs in that layer:
curl -sS -o /dev/null -D - -H "X-Vault-Token: $VAULT_TOKEN" \
  https://vault.example.com:8200/v1/sys/health
  1. Turn on response headers so clients can see their own budget and back off intelligently instead of hammering:
vault write sys/quotas/config enable_rate_limit_response_headers=true

With this enabled, every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset, and rejections carry Retry-After.

  1. Raise or retarget the offending quota. Rather than lifting the global default for everyone, define a specific quota for the busy path:
vault write sys/quotas/rate-limit/kv-app-prod \
  path="secret/data/app/prod" \
  rate=2000 \
  interval=1s \
  block_interval=0

Setting block_interval=0 means clients recover on the next interval rather than being locked out.

  1. Review the global default. A low default configured during initial hardening is a common cause of mystery throttling on new mounts:
vault read sys/quotas/config
vault write sys/quotas/config rate_limit_exempt_paths="sys/health,sys/generate-recovery-token/attempt"
  1. If a single namespace is responsible, scope a quota to it rather than punishing the whole cluster:
vault write -namespace=tenant-b sys/quotas/rate-limit/tenant-b \
  path="" \
  rate=500 \
  interval=1s

Namespaces are a Vault Enterprise feature; if the namespace itself is missing you will get a different failure, described in Vault error: namespace not found.

  1. Fix the client. Retrying immediately on 429 makes the problem worse. Honour Retry-After, add jitter, and cache the token and the secret for its lease duration:
{
  "vault": {
    "address": "https://vault.example.com:8200",
    "max_retries": 5,
    "retry_base_delay_ms": 200,
    "retry_max_delay_ms": 5000,
    "retry_jitter": true,
    "respect_retry_after": true,
    "secret_cache_ttl_seconds": 300
  }
}

The official Vault client libraries already implement exponential backoff on 429 and 5xx; make sure you have not disabled it while chasing an unrelated timeout.

Prevention

  • Define explicit per-path quotas for high-traffic mounts instead of relying on one global number that nobody remembers setting.
  • Keep enable_rate_limit_response_headers on so clients can self-regulate before they trip the limit.
  • Alert on vault.quota.rate_limit.violation so throttling is visible before it becomes an incident.
  • Leave block_interval at zero unless you are deliberately defending against abuse; short bursts should not cause multi-minute lockouts.
  • Cache tokens and leases in application code — re-authenticating per request is the single biggest driver of avoidable volume.
  • Exempt health and unseal-related paths from quotas so monitoring and recovery never get throttled.
  • Code: 503. Errors: * Vault is sealed — the node is sealed, not throttled; see Vault error: failed to unseal invalid key.
  • Code: 503. Errors: * node is a standby — the request hit a standby without request forwarding, a routing problem rather than a quota.
  • 429 Too Many Requests with an HTML body — emitted by nginx, an ALB, or an API gateway in front of Vault.
  • Code: 400. Errors: * lease count quota exceeded — the lease-count quota, a distinct limit on active leases (Vault Enterprise).

Frequently Asked Questions

Is a 429 from Vault the same as a 503? No. 429 means a resource quota rejected the request while Vault was healthy and serving. 503 means the node cannot serve at all — it is sealed, in standby without forwarding, or still initialising. Check vault status before touching quota configuration.

Do rate limit quotas apply cluster-wide? No, they are enforced per node. A cluster of three active-capable nodes with a 1000/s quota can serve close to 3000/s in aggregate depending on how your load balancer distributes traffic. Size quotas with your node count in mind.

What is a lease count quota? A lease count quota (Vault Enterprise) caps the number of active leases a path or namespace may hold, rather than the request rate. It protects against lease explosion from short-TTL dynamic credentials and returns a different error message, so do not confuse the two.

Why does raising the rate not help? Because only the most specific matching quota applies. Raising the global default has no effect if a narrower quota on the mount or path is the one firing — list the quotas and read the specific one. 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.