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

Vault Error: 'namespace not found' on Enterprise and HCP Vault Requests

Quick answer

Fix Vault's 'namespace not found' error: set VAULT_NAMESPACE correctly, use the -namespace flag or X-Vault-Namespace header, and resolve nested paths, token scoping, and Terraform provider gaps.

  • #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 kv get -namespace=finance/prod secret/db/creds
Error making API request.

URL: GET https://vault.internal:8200/v1/secret/data/db/creds
Code: 404. Errors:

* namespace not found

You may instead see the failure surface as a permission error, because the path exists in one namespace but not the one you addressed:

Error making API request.

URL: PUT https://vault.internal:8200/v1/auth/approle/login
Code: 403. Errors:

* permission denied

Or, from the Terraform Vault provider:

Error: error reading from Vault: Error making API request.

URL: GET https://vault.internal:8200/v1/sys/internal/ui/mounts/secret/db/creds
Code: 404. Errors:

* namespace not found

What It Means

Namespaces are a Vault Enterprise feature (also available on HCP Vault Dedicated) that carve a single Vault cluster into isolated tenants. Each namespace gets its own policies, auth methods, secrets engines, tokens, identities, and audit visibility. There is always a root namespace, and child namespaces hang beneath it in a path hierarchy such as finance/, finance/prod/, finance/prod/payments/. Vault Community Edition has no namespaces at all — every request implicitly targets root, and any attempt to address a namespace returns this same 404 namespace not found because the resolver has nothing to resolve.

When a request arrives, Vault resolves the namespace before it resolves the path. The namespace comes from the X-Vault-Namespace header (which the CLI sets from -namespace or VAULT_NAMESPACE) or from a namespace prefix embedded in the URL path itself. Only after picking a namespace does Vault look up the mount. So a mount at secret/ in finance/prod is a completely different mount from secret/ in root — same path string, different object. namespace not found means the resolver could not match the namespace you named; permission denied on a path you know exists usually means the resolver did match, but a different namespace than you intended.

Common Causes

  • VAULT_NAMESPACE is unset, or set to a stale value left over from an earlier shell session.
  • The namespace name is misspelled, or the nesting is wrong — prod instead of the full finance/prod.
  • The token was created in a different namespace; tokens are scoped to their creating namespace and cannot be used in a sibling.
  • A trailing-slash or leading-slash mismatch in a nested path, particularly when the namespace is being concatenated into a URL by a client library.
  • The namespace exists under a parent you did not account for, so a relative reference resolves differently than expected.
  • A Terraform provider, Kubernetes sidecar, or SDK client was configured without a namespace and silently targets root.

Diagnostic Commands

First, see what your environment is actually sending. This catches the majority of cases in seconds:

env | grep -i vault
vault status

List the namespaces visible from where you currently are. Note that vault namespace list shows only the direct children of your current namespace:

vault namespace list
vault namespace list -namespace=finance

Walk the hierarchy explicitly to confirm the full path of the namespace you want:

vault namespace lookup -namespace=finance prod

Inspect your token — the namespace_path field tells you which namespace it belongs to, which is the single most useful field when debugging this:

vault token lookup -format=json | jq '{namespace_path, policies, entity_id, ttl}'

Confirm the mount actually exists in the namespace you are addressing:

vault secrets list -namespace=finance/prod
vault auth list -namespace=finance/prod

You can bypass the CLI entirely and send the header yourself, which distinguishes a CLI configuration problem from a server-side one:

curl -sS -w '\n%{http_code}\n' \
  --header "X-Vault-Token: $VAULT_TOKEN" \
  --header "X-Vault-Namespace: finance/prod" \
  https://vault.internal:8200/v1/secret/data/db/creds

The equivalent path-prefixed form is also valid, and is what you want when a client cannot set custom headers:

curl -sS \
  --header "X-Vault-Token: $VAULT_TOKEN" \
  https://vault.internal:8200/v1/finance/prod/secret/data/db/creds

Step-by-Step Resolution

  1. Set the namespace explicitly and confirm it round-trips. Prefer the full path from root, without a leading slash:
export VAULT_NAMESPACE="finance/prod"
vault secrets list
  1. If a single command needs a different namespace, use the flag rather than mutating the environment. The flag overrides VAULT_NAMESPACE for that invocation:
vault kv get -namespace=finance/staging secret/db/creds
  1. Create the namespace if it genuinely does not exist. Create parents before children — vault namespace create does not create intermediate namespaces implicitly:
vault namespace create finance
vault namespace create -namespace=finance prod
vault namespace list -namespace=finance
  1. Authenticate inside the target namespace. A token minted in root is not usable in a child namespace unless it is a root token; a token minted in finance/prod is not usable in finance/staging:
vault login -namespace=finance/prod -method=approle \
  role_id="$ROLE_ID" secret_id="$SECRET_ID"

vault token lookup -format=json | jq -r '.data.namespace_path'
  1. Write policies and mounts in the namespace that will use them. Policies are namespace-local; a policy named db-reader in root has no effect in finance/prod:
vault policy write -namespace=finance/prod db-reader - <<'EOF'
path "secret/data/db/*" {
  capabilities = ["read", "list"]
}
EOF

vault secrets enable -namespace=finance/prod -path=secret kv-v2
  1. Fix API and Terraform clients that silently default to root. The Vault Terraform provider takes a namespace argument on the provider block, and individual resources can override it:
provider "vault" {
  address   = "https://vault.internal:8200"
  namespace = "finance/prod"
}

resource "vault_kv_secret_v2" "db" {
  mount = "secret"
  name  = "db/creds"
  data_json = jsonencode({
    username = "app"
  })
}

For SDK clients, set the namespace on the client object rather than gluing it onto every path:

{
  "VAULT_ADDR": "https://vault.internal:8200",
  "VAULT_NAMESPACE": "finance/prod"
}

If your client is failing TLS validation while you debug this, resist the urge to leave VAULT_SKIP_VERIFY=true in place. Use it only as a throwaway diagnostic to separate a TLS trust failure from a namespace failure, then set VAULT_CACERT to the proper CA bundle before you move on.

Prevention

  • Bake VAULT_NAMESPACE into per-environment shell profiles or direnv files so operators cannot accidentally act on root.
  • Use full paths from root everywhere (finance/prod) instead of relative references that change meaning with context.
  • Standardise on no leading slash and no trailing slash in namespace strings across CI, Terraform, and SDK configuration.
  • Grant each team’s AppRole or OIDC role inside its own namespace so a wrong-namespace token fails fast and loudly.
  • Include the namespace in the CI job name or log preamble so a misdirected pipeline is obvious in the run output.
  • Keep the namespace tree shallow and documented; deeply nested hierarchies make path mistakes far more likely.
  • permission denied on a path you can see in the UI — the request resolved to a different namespace than the one you were browsing.
  • no handler for route "secret/data/db/creds" — the namespace resolved correctly but the mount does not exist there.
  • 1 error occurred: * namespace not found from vault namespace delete — you targeted a child from the wrong parent.
  • invalid token when switching namespaces — tokens do not cross namespace boundaries; see Vault error: wrapping token expired.

Frequently Asked Questions

Does Vault Community Edition support namespaces? No. Namespaces are a Vault Enterprise feature and are also available on HCP Vault Dedicated. On Community Edition, any request carrying X-Vault-Namespace for a non-root namespace returns namespace not found, because there is no namespace tree to resolve against. If you need tenant isolation on Community Edition, use separate mounts with tightly scoped policies, or separate clusters.

Can I use a root-namespace token in a child namespace? A true root token works everywhere. Any other token is bound to the namespace it was created in, and its policies are evaluated in that namespace. To operate in a child, authenticate against an auth method mounted in that child, or use identity groups with external_policies designed for cross-namespace access.

Why did my path work with a trailing slash but not without one? Vault treats the namespace segment and the mount path separately, and some clients concatenate them naively. finance/prod plus secret/data/x should produce finance/prod/secret/data/x — a client that adds its own slash can produce a double slash, which resolves to an empty namespace segment and fails. Normalise the namespace string once, in one place.

Do I need to recreate policies in every namespace? Yes for namespace-local policies — they do not inherit downward. (Vault Enterprise) clusters can share identity groups and entities across namespaces, which is the usual way to grant a central platform team access to many child namespaces without duplicating tokens. For more Enterprise-feature troubleshooting, 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.