1. Introduction

A ResourceQuota exceeded error blocks pod creation in a namespace. When you try to deploy, scale, or create a new pod and the namespace has reached its quota limit, Kubernetes rejects the request immediately with a clear error. The deployment sits with fewer replicas than desired, HPA can't scale up, and CI/CD deployments fail — all because a quota limit was hit.

ResourceQuotas are intentional administrative controls, not bugs. This guide covers how to diagnose which quota is blocking you, how to adjust quota when appropriate, and how to avoid hitting quota limits in the first place.

2. What ResourceQuota Means

A ResourceQuota object sets hard limits on the aggregate resource consumption within a namespace. It can limit: CPU requests and limits, memory requests and limits, number of pods, number of PVCs, total storage, number of Services, ConfigMaps, Secrets, and more. When any limit is hit, all new resource creation of that type fails until usage drops below the limit.

3. Common Causes

4. Step-by-Step Diagnosis and Fix

Step 1: Identify the quota and current usage

# Check all ResourceQuotas in the namespace
kubectl get resourcequota -n <namespace>

# Detailed view showing used vs hard limits
kubectl describe resourcequota -n <namespace>
# Example output:
# Name:            default-quota
# Namespace:       production
# Resource         Used    Hard
# --------         ----    ----
# limits.cpu       14      16
# limits.memory    14Gi    16Gi
# pods             45      50
# requests.cpu     7       8

# The specific failed operation will also show in:
kubectl get events -n <namespace> --field-selector reason=FailedCreate | head -10

Step 2: Find what's consuming quota

# Find memory and CPU hogs
kubectl top pods -n <namespace> --sort-by=memory | head -20
kubectl top pods -n <namespace> --sort-by=cpu | head -20

# Find pods with inflated limits vs actual usage
kubectl get pods -n <namespace> -o json | jq -r '
  .items[] |
  "\(.metadata.name): cpu_limit=\(.spec.containers[0].resources.limits.cpu // "none"),
   mem_limit=\(.spec.containers[0].resources.limits.memory // "none")"'

# Count pods including failed ones (they count against pod quota)
kubectl get pods -n <namespace> --field-selector status.phase=Failed | wc -l

Step 3: Free up quota — clean old pods

# Delete failed/completed pods that still count against quota
kubectl delete pods -n <namespace> --field-selector status.phase=Failed
kubectl delete pods -n <namespace> --field-selector status.phase=Succeeded

# For Jobs: delete completed jobs (which keep pods)
kubectl delete jobs -n <namespace> --field-selector status.conditions[0].type=Complete

Step 4: Fix oversized resource limits

# If pods have unnecessarily high limits, right-size them
# This reduces quota consumption without removing workloads

# Example: reduce overly generous memory limits
kubectl set resources deployment my-app -n <namespace>   --requests=cpu=100m,memory=256Mi   --limits=cpu=500m,memory=512Mi

# Use VPA recommendations to right-size before adjusting manually:
kubectl describe vpa <vpa-name> -n <namespace>

Step 5: Increase or modify the ResourceQuota

# Edit the quota directly (requires cluster-admin or quota management permissions)
kubectl edit resourcequota <quota-name> -n <namespace>

# Or patch a specific limit:
kubectl patch resourcequota <quota-name> -n <namespace>   --type='json'   -p='[{"op":"replace","path":"/spec/hard/pods","value":"100"}]'

# Or create a new quota (if none exists):
apiVersion: v1
kind: ResourceQuota
metadata:
  name: production-quota
  namespace: production
spec:
  hard:
    requests.cpu: "8"
    requests.memory: 16Gi
    limits.cpu: "16"
    limits.memory: 32Gi
    pods: "100"

5. Verification Steps

# After adjusting quota or freeing resources:
kubectl describe resourcequota -n <namespace>
# Used values should be below Hard limits

# Test that new pods can be created
kubectl run test-pod --image=nginx -n <namespace> --rm --restart=Never -- echo "quota ok"

# Deployments that were blocked should now converge
kubectl get deployment -n <namespace>
# AVAILABLE should equal DESIRED

6. Common Mistakes

7. Prevention Tips

8. FAQ

I deleted old pods but quota usage didn't drop. Why?

Quota counts the aggregate resource requests and limits of all pods with a managed lifecycle — not just Running pods. Check if there are pods in Pending, Unknown, or Init states that are still counting against quota: kubectl get pods -n <namespace> --field-selector status.phase!=Running,status.phase!=Failed,status.phase!=Succeeded

Can I temporarily bypass ResourceQuota for an emergency deployment?

A cluster-admin can temporarily increase the quota: kubectl patch resourcequota <name> -n <namespace> --type=json -p='[{"op":"replace","path":"/spec/hard/pods","value":"200"}]'. Remember to revert after the emergency. Alternatively, deploy to a different namespace that has headroom. Never permanently relax quotas without team review.

9. Summary

Quota type hitSymptomFix
podsFailedCreate: quota exceededDelete old pods; increase pod quota
requests.cpu/memoryPod creation failsRight-size requests; increase quota
limits.cpu/memoryPod creation fails if limits setReduce oversized limits; increase quota
count/persistentvolumeclaimsPVC creation failsDelete unused PVCs; increase pvc quota
requests.storagePVC creation failsDelete unused PVCs; increase storage quota

Explore More in This Category

Explore more in this category: Kubernetes guides. Browse all DevOps Compass articles or jump to: Kubernetes, AWS, CI/CD, Containers, Monitoring, Networking.