Elasticsearch helm chart gives AccessDenied exception
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
The AccessDenied exception when deploying Elasticsearch via a Helm chart is almost always a file permission issue on the persistent volume. Elasticsearch needs to read and write to its data directory, but the container runs as a non-root user (UID 1000 by default) while the persistent volume is often created with root-only permissions. The fix is to configure an initContainer that sets the correct ownership, or adjust the securityContext in the Helm values.
The Error
Or in the pod logs:
The Elasticsearch process cannot write to its data directory because the filesystem permissions do not allow the Elasticsearch user (UID 1000) to access it.
Root Cause
- Elasticsearch runs as user
elasticsearch(UID 1000, GID 1000) by default - Persistent volumes provisioned by cloud providers (EBS, GCE PD, Azure Disk) are often created with
root:rootownership - The Elasticsearch container cannot write to a root-owned directory as UID 1000
Fix 1: initContainer to Set Permissions (Most Common)
Add an initContainer that runs as root and changes the data directory ownership before Elasticsearch starts:
Fix 2: Set fsGroup in Security Context
The fsGroup setting tells Kubernetes to change the group ownership of all files in mounted volumes to the specified GID:
When fsGroup: 1000 is set, Kubernetes recursively changes the group of files on the volume to GID 1000 before the container starts. This is the cleanest solution when your cluster and storage class support it.
Fix 3: Set securityContext on the Container
This ensures the container runs as UID/GID 1000. Combined with fsGroup, this covers most permission scenarios.
Fix 4: Use emptyDir for Testing
For development or testing where persistence is not needed:
emptyDir volumes are writable by default and do not have the permission issues of persistent volumes. Data is lost when the pod is deleted.
Debugging Steps
Helm Chart-Specific Configurations
Elastic Official Chart (elastic/elasticsearch)
Bitnami Chart (bitnami/elasticsearch)
ECK (Elastic Cloud on Kubernetes)
Common Pitfalls
- initContainer volume mount name mismatch: The
volumeMounts.namein the initContainer must match the actual volume name defined by the Helm chart. Check the chart's templates to find the correct volume name (e.g.,elasticsearch-masterfor the Elastic chart,datafor Bitnami). - PodSecurityPolicy blocking privileged initContainers: If your cluster has PodSecurityPolicies (PSPs) or OPA Gatekeeper policies that block privileged containers or root users, the
fix-permissionsinitContainer will fail. Create a PSP exception or usefsGroupinstead. - Storage class not supporting
fsGroup: Some storage classes (notably certain NFS provisioners) do not respect thefsGroupsetting. In this case, the initContainer approach is the only reliable solution. - Elasticsearch version differences: Elasticsearch 7.x and 8.x use different UIDs. Verify the correct UID by checking the Dockerfile or running
kubectl exec -- idinside the pod. Using the wrong UID leaves the permission problem unsolved. - Forgetting to set permissions on all data paths: Elasticsearch may use multiple paths (
/usr/share/elasticsearch/data,/usr/share/elasticsearch/logs,/usr/share/elasticsearch/config). Ensure all writable paths have correct ownership, especially if you mount separate volumes for logs or snapshots.
Summary
- The
AccessDeniedexception is caused by persistent volumes owned by root while Elasticsearch runs as UID 1000 - Fix with an
initContainerthat runschown -R 1000:1000on the data directory - Alternatively, set
fsGroup: 1000inpodSecurityContextto let Kubernetes handle ownership - Bitnami charts have
volumePermissions.enabled: trueas a built-in option - Always verify volume mount names match between the initContainer and the chart's volume definitions
- Use
kubectl exec -- ls -lato confirm file ownership on the data directory
Related reading
- Empty ADDRESS kubernetes ingress
- Enable Access for Kubernetes Dashboard via external VIP or Floating IP
- Enable Ingress controller on Docker Desktop with WLS2
- Enable SSL connection for Kubernetes Dashboard
- Elasticsearch on AWS RED and reroute not allowed
- ElasticsearchSinkConnector can't connect to Elastic
- endpoints “default-http-backend” not found in Ingress resource
- Ensuring at most a single instance of job executing on Kubernetes and writing into Postgresql

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.