How to fix MountVolume.SetUp failed for volume "secret": secrets "database-credentials" not found in Kubernetes

KubernetesBEGINNERHIGHUpdated Dec 6, 2025· 179 views

A pod references a Secret that doesn't exist or is in a different namespace. Secrets are namespace-scoped resources; pods can only reference Secrets in their own namespace. Fix by creating the missing Secret in the correct namespace or using External Secrets Operator for externalized secret management.

Quick fix

Fixes MountVolume.SetUp failed for volume "secret": secrets "database-credentials" not found

kubectl get secrets -n <pod-namespace>
kubectl describe secret <secret-name> -n <pod-namespace>
  1. Check if the Secret exists in the pod's namespace
  2. Check pod namespace and secret reference
  3. Create the missing Secret in the correct namespace
  4. If Secret is in different namespace, copy it or update pod reference
kubernetes — error
kubectl get secrets -n <pod-namespace>
kubectl describe secret <secret-name> -n <pod-namespace>
MountVolume.SetUp failed for volume "secret": secrets "database-credentials" not found

What this error means

Kubernetes Secrets are namespace-scoped configuration objects used to store sensitive data like database credentials, API keys, and TLS certificates. When a pod spec references a Secret by name, Kubernetes expects to find that Secret in the pod's namespace. If the Secret doesn't exist or is in a different namespace, the kubelet cannot mount the secret volume or inject it as an environment variable. Unlike some other Kubernetes resources, there is no built-in mechanism to access Secrets across namespaces—each namespace is isolated by default. For externalized secret management, you can use the External Secrets Operator or Secrets Store CSI driver to pull secrets from external vaults.

Typical symptoms

  • Pod remains in Pending state indefinitely
  • kubectl describe pod shows "MountVolume.SetUp failed for volume...secrets...not found"
  • Pod cannot start with CreateContainerConfigError
  • Environment variables injected via secretKeyRef are not set
  • Volume mount fails for secret volumes
  • Pod logs show "Secret not found" or similar error
  • Multiple restart attempts with consistent failures

Common causes

  1. Secret has not been created before pod deployment (race condition)
  2. Secret exists in different namespace than the pod
  3. Typo or case mismatch in Secret name referenced in pod spec
  4. Secret was deleted while pod still references it
  5. Secret creation skipped in deployment pipeline
  6. CSI driver or External Secrets Operator not properly configured (if using external secrets)
  7. Secrets Store CSI driver not installed or SecretProviderClass not created

How to fix "MountVolume.SetUp failed for volume "secret": secrets "database-credentials" not found"

1Check if the Secret exists in the pod's namespace

List all Secrets in the namespace where the pod is running:

bash
kubectl get secrets -n <pod-namespace>
kubectl describe secret <secret-name> -n <pod-namespace>

The secret name and namespace must match exactly what's referenced in the pod spec. If the secret doesn't appear, move to the next step.

2Check pod namespace and secret reference

Examine the pod spec to see what Secret it's referencing:

bash
kubectl describe pod <pod-name> -n <pod-namespace>
kubectl get pod <pod-name> -n <pod-namespace> -o yaml | grep -A5 -i secret

Look for:
- Secret name in spec.volumes[].secret.secretName (for secret volumes)
- Secret name in spec.containers[].env[].valueFrom.secretKeyRef.name (for env vars)

Verify the pod is in the correct namespace.

bash
kubectl config get-context  # Check current context/namespace
kubectl get pods -A | grep <pod-name>  # Find all pods with that name
3Create the missing Secret in the correct namespace

If the Secret doesn't exist, create it. Choose the appropriate Secret type:

Generic Secret (key-value pairs):

bash
kubectl create secret generic <secret-name> \
  --from-literal=username=admin \
  --from-literal=password=mypassword \
  -n <pod-namespace>

From a file:

bash
kubectl create secret generic <secret-name> \
  --from-file=config.json \
  -n <pod-namespace>

Docker registry credentials:

bash
kubectl create secret docker-registry <secret-name> \
  --docker-server=docker.io \
  --docker-username=<username> \
  --docker-password=<password> \
  -n <pod-namespace>

TLS certificate:

bash
kubectl create secret tls <secret-name> \
  --cert=path/to/cert.crt \
  --key=path/to/private.key \
  -n <pod-namespace>

Or use a YAML manifest:

yaml
apiVersion: v1
kind: Secret
metadata:
  name: database-credentials
  namespace: production
type: Opaque
stringData:
  username: admin
  password: secret-password

Then apply: kubectl apply -f secret.yaml

4If Secret is in different namespace, copy it or update pod reference

Secrets are namespace-isolated. You have two options:

Option A: Copy the Secret to the pod's namespace

bash
kubectl get secret <secret-name> -n <source-namespace> -o yaml | \
  sed 's/namespace: <source-namespace>/namespace: <pod-namespace>/' | \
  kubectl apply -f -

Then verify in the new namespace:

bash
kubectl get secrets -n <pod-namespace>

Option B: Move pod to same namespace as Secret (if pod shouldn't be elsewhere)

bash
kubectl get pod <pod-name> -n <source-namespace> -o yaml | \
  sed 's/namespace: <source-namespace>/namespace: <pod-namespace>/' | \
  kubectl apply -f -

kubectl delete pod <pod-name> -n <source-namespace>
5Verify pod can now access the Secret

After creating the Secret, the pod should start automatically:

bash
kubectl get pod <pod-name> -n <pod-namespace>
kubectl describe pod <pod-name> -n <pod-namespace>

Pod status should change from Pending to Running. Check logs to confirm:

bash
kubectl logs <pod-name> -n <pod-namespace>

If still failing, check if there are other issues (like a missing key within the Secret).

6For external secrets, deploy External Secrets Operator

If secrets are stored in an external vault (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault), use External Secrets Operator:

Install via Helm:

bash
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
  -n external-secrets-system --create-namespace

Create SecretStore (points to external vault):

yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: aws-secrets
  namespace: production
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets-sa

Create ExternalSecret (pulls secret from vault):

yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets
    kind: SecretStore
  target:
    name: database-credentials  # Name of Kubernetes Secret to create
    creationPolicy: Owner
  data:
  - secretKey: username
    remoteRef:
      key: prod/db/username
  - secretKey: password
    remoteRef:
      key: prod/db/password

External Secrets Operator automatically creates the Kubernetes Secret from vault data.

Advanced notes

Secrets are stored unencrypted in etcd by default; enable encryption at rest in Kubernetes to protect sensitive data. Use RBAC to restrict Secret access—not all service accounts should read all secrets. For multi-namespace secret sharing without External Secrets, use a namespace-per-tenant model and handle replication in your deployment pipeline (Helm, Kustomize). Sealed Secrets and Sealed Secrets Operator provide GitOps-friendly encrypted secrets. External Secrets Operator supports 40+ external vaults and can aggregate secrets from multiple sources. Rotation: ensure external secret backends support TTL/rotation; External Secrets Operator can be configured to refresh periodically (refreshInterval). For CI/CD, inject secrets at pod creation time rather than committing to version control. Large binary secrets (certificates, key material) should use Secret type "Opaque" with base64 encoding. Monitor Secret access via audit logs; most breaches involve leaked secrets left in logs or config files.

Frequently asked questions

What does "MountVolume.SetUp failed for volume "secret": secrets "database-creden" mean?
Kubernetes Secrets are namespace-scoped configuration objects used to store sensitive data like database credentials, API keys, and TLS certificates. When a pod spec references a Secret by name, Kubernetes expects to find that Secret in the pod's namespace. If the Secret doesn't exist or is in a different namespace, the kubelet cannot mount the secret volume or inject it as an environment variable.
How do I fix "MountVolume.SetUp failed for volume "secret": secrets "database-creden"?
A pod references a Secret that doesn't exist or is in a different namespace. Secrets are namespace-scoped resources; pods can only reference Secrets in their own namespace. Fix by creating the missing Secret in the correct namespace or using External Secrets Operator for externalized secret management.
What causes "MountVolume.SetUp failed for volume "secret": secrets "database-creden"?
Secret has not been created before pod deployment (race condition) Secret exists in different namespace than the pod Typo or case mismatch in Secret name referenced in pod spec
Is the "MountVolume.SetUp failed for volume "secret": secrets "database-creden" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading