AWS EKS You must be logged in to the server (Unauthorized)
Encountering "You must be logged in to the server (Unauthorized)" when interacting with AWS EKS means kubectl cannot authenticate; this guide explains how to fix it.
What This Error Means
When you see the error error: You must be logged in to the server (Unauthorized) after running a kubectl command against an AWS EKS cluster, it indicates that your kubectl client failed to authenticate with the Kubernetes API server running within your EKS cluster. This isn't necessarily an issue with the cluster itself being down, but rather a problem with how your client is attempting to prove its identity or its authorization once identified. Essentially, the API server rejected your request because it couldn't verify who you are, or because the identity you presented lacks the necessary permissions to access the API. In my experience, this is one of the most common initial hurdles engineers face when setting up kubectl for EKS.
Why It Happens
Interacting with an EKS cluster using kubectl involves a multi-layered authentication process that's unique to AWS. Unlike self-managed Kubernetes clusters that might use service account tokens, client certificates, or basic authentication, EKS leverages AWS Identity and Access Management (IAM) for authentication.
Here's the simplified flow:
1. You run a kubectl command.
2. kubectl uses your kubeconfig file to determine the cluster context, including the exec plugin responsible for EKS authentication.
3. This exec plugin (historically aws-iam-authenticator, now often integrated into kubectl-eks or aws CLI) generates a temporary signed URL using your active AWS credentials.
4. This signed URL is then used to make an API call to the EKS control plane.
5. The EKS control plane validates the AWS credentials embedded in the signed URL via AWS STS (Security Token Service).
6. If the credentials are valid, EKS then checks its internal aws-auth ConfigMap within the kube-system namespace to map the AWS IAM identity (user or role) to a Kubernetes user or group.
7. Finally, standard Kubernetes Role-Based Access Control (RBAC) takes over, evaluating the permissions assigned to the mapped Kubernetes user/group.
The "Unauthorized" error typically means the process failed at step 4, 5, or 6:
* Step 4/5 (AWS Authentication Failure): Your AWS credentials are not valid, expired, or don't have permission to eks:DescribeCluster or sts:GetCallerIdentity for the specified cluster/region.
* Step 6 (EKS aws-auth Mapping Failure): Your valid AWS IAM identity is not correctly mapped to a Kubernetes user or group in the aws-auth ConfigMap.
I've seen this in production when developers accidentally switched AWS profiles or regions, causing the kubectl command to present the wrong AWS identity to the cluster.
Common Causes
This error generally boils down to a few key areas where the authentication chain breaks:
- Incorrect AWS Credentials: Your AWS CLI is configured with credentials that are expired, incorrect, or belong to an account/IAM entity that doesn't have access to the EKS cluster. This is often the first place I check.
- Wrong
kubeconfigContext: Yourkubectlcommand is attempting to use the wrong cluster context from yourkubeconfigfile, pointing to a different cluster or even a non-EKS cluster where theexecplugin isn't relevant. - Outdated or Missing
kubeconfig: Yourkubeconfigfile (typically~/.kube/config) doesn't contain the correct EKS cluster entry, or it's malformed. For EKS, thekubeconfigneeds specificexecblocks to invoke the AWS authentication helper. - Missing or Misconfigured
aws-iam-authenticator/kubectl-eksPlugin: Theexecplugin specified in yourkubeconfig(usuallyaws-iam-authenticatoror thekubectl-eksplugin that comes with the AWS CLI) is not installed, not in your PATH, or is an outdated version. - IAM User/Role Not Mapped in
aws-authConfigMap: Even if your AWS credentials are valid, the specific IAM user or role you're authenticating as might not be present in the EKS cluster'saws-authConfigMap. This ConfigMap is crucial as it tells EKS which AWS identities map to which Kubernetes RBAC identities. - Network Connectivity Issues: Less common for "Unauthorized," but a blocked connection to the EKS API endpoint could manifest similarly if the initial handshake fails completely.
- AWS STS Permissions: The IAM user or role you're using might lack the
sts:AssumeRoleorsts:GetCallerIdentitypermissions required for the authentication plugin to generate the necessary temporary credentials.
Step-by-Step Fix
Let's systematically troubleshoot this error.
-
Verify Your AWS CLI Configuration and Identity
First, ensure your AWS CLI is configured correctly and you're using the intended AWS identity.
```bash
# Check your active AWS CLI profile
aws configure listConfirm the AWS identity you're currently using
aws sts get-caller-identity
`` Ensure theAccountandArnfromget-caller-identitymatch the expected AWS account and IAM user/role that *should* have access to your EKS cluster. If this is incorrect, set the right profile usingexport AWS_PROFILE=your-profile-nameoraws configure`. -
Ensure
kubeconfigis Correct and Updated
For EKS, the recommended way to generate or update yourkubeconfigis using the AWS CLI. This command automatically sets up theexecplugin for authentication.```bash
Update your kubeconfig for the specific EKS cluster and region
Replace 'my-cluster-name' with your EKS cluster's name
Replace 'us-west-2' with your EKS cluster's region
aws eks update-kubeconfig --name my-cluster-name --region us-west-2
If you want to specify a non-default kubeconfig file path:
aws eks update-kubeconfig --name my-cluster-name --region us-west-2 --kubeconfig /path/to/my/custom/kubeconfig
`` This command will add or update the cluster entry in your~/.kube/config(or the path you specify). It also ensures theexecblock pointing to theaws-iam-authenticatororkubectl-eks` plugin is correctly configured. -
Verify
kubectlContext
After updatingkubeconfig, make surekubectlis actually using the correct context.
```bash
# List all available contexts
kubectl config get-contextsSwitch to the correct context if needed. The name is usually
arn:aws:eks:REGION:ACCOUNT_ID:cluster/CLUSTER_NAME
kubectl config use-context arn:aws:eks:us-west-2:123456789012:cluster/my-cluster-name
`` Theupdate-kubeconfig` command usually sets the context automatically, but it's good to double-check. -
Check
aws-iam-authenticator/kubectl-eksPlugin Installation
Theexecplugin needs to be installed and accessible in your system's PATH.- If you're using
aws-iam-authenticatordirectly:
bash which aws-iam-authenticator aws-iam-authenticator version
If it's not found or outdated, install/update it. - If you're using the newer AWS CLI v2
kubectl-eksplugin:
bash aws eks get-token --cluster-name my-cluster-name # Test the plugin directly # You should see token details if it's working
Theupdate-kubeconfigcommand should configurekubectlto use whichever is appropriate based on your AWS CLI version. Ensure your AWS CLI is up-to-date.
- If you're using
-
Examine the EKS
aws-authConfigMap
This is often the culprit if your AWS credentials andkubeconfigare otherwise correct. Theaws-authConfigMap maps AWS IAM entities to Kubernetes RBAC.
bash kubectl get configmap aws-auth -n kube-system -o yaml
Look for themapUsersandmapRolessections. Your IAM user or the role you are assuming must be listed there, mapped to a Kubernetesusernameandgroups.
For example, if you arearn:aws:iam::123456789012:user/daniel.kovacs, you'd expect to see:
yaml # ... data: mapUsers: | - userarn: arn:aws:iam::123456789012:user/daniel.kovacs username: daniel.kovacs groups: - system:masters # ...
If your entry is missing or incorrect, you need to update this ConfigMap. The safest way is often througheksctlor infrastructure-as-code tools like Terraform or CloudFormation. Manual edits withkubectl edit cm aws-auth -n kube-systemare possible but risky, as syntax errors can lock you out. -
Verify IAM Permissions
Ensure the IAM user or role you are using has the necessary permissions. At a minimum, it needseks:DescribeClusterand permission to perform STS actions likests:GetCallerIdentityfor theaws-iam-authenticatorto function. For full admin access, it would typically be mapped tosystem:mastersin theaws-authConfigMap.- Common EKS access policy:
AmazonEKSClusterPolicyfor cluster management (thoughsystem:mastersmapping provides full control within K8s). - STS permissions:
sts:GetCallerIdentityfor the principal, andsts:AssumeRoleif cross-account access or role assumption is involved.
- Common EKS access policy:
Code Examples
Here are some concise, copy-paste ready examples for critical checks:
1. Check Current AWS Identity:
aws sts get-caller-identity
2. Update kubeconfig for an EKS Cluster:
aws eks update-kubeconfig --name my-production-cluster --region us-east-1
3. List and Use kubectl Contexts:
# List all contexts
kubectl config get-contexts
# Switch to a specific EKS context (replace with your cluster's context name)
kubectl config use-context arn:aws:eks:us-east-1:123456789012:cluster/my-production-cluster
4. Inspect the aws-auth ConfigMap:
kubectl get configmap aws-auth -n kube-system -o yaml
Expected output snippet demonstrating a user mapping:
apiVersion: v1
data:
mapUsers: |
- userarn: arn:aws:iam::123456789012:user/my-dev-user
username: my-dev-user
groups:
- system:authenticated
- custom-dev-group
mapRoles: |
- rolearn: arn:aws:iam::123456789012:role/my-dev-role
username: my-dev-role
groups:
- custom-dev-group
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
# ... rest of metadata
Environment-Specific Notes
The troubleshooting steps remain similar, but the source of the AWS credentials and kubeconfig can vary:
-
Local Development Environment:
- Credentials: Typically sourced from
~/.aws/credentialsor environment variables likeAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN. Ensure these are correctly set and not expired. kubeconfig: Usually~/.kube/config. Ensure it's not overridden byKUBECONFIGenvironment variable if you're not expecting it.
- Credentials: Typically sourced from
-
CI/CD Pipelines (e.g., GitHub Actions, GitLab CI, Jenkins):
- Credentials: Often provided via temporary credentials assumed by an IAM role (e.g., OIDC for GitHub Actions, service account roles for Jenkins running in Kubernetes, or directly set as environment variables). Ensure the IAM role has the necessary permissions (
sts:AssumeRoleandeks:DescribeCluster). I've seen this in production when the CI/CD role didn't have thests:AssumeRoleWithWebIdentitypermission necessary for OIDC. kubeconfig: Usually generated dynamically within the pipeline usingaws eks update-kubeconfig. Ensure the correct cluster name and region are passed. Thekubectl-eksplugin also needs to be available in the CI/CD runner's environment.
- Credentials: Often provided via temporary credentials assumed by an IAM role (e.g., OIDC for GitHub Actions, service account roles for Jenkins running in Kubernetes, or directly set as environment variables). Ensure the IAM role has the necessary permissions (
-
EC2 Instances within the same AWS account:
- Credentials: Best practice is to attach an IAM instance profile to the EC2 instance. This provides temporary credentials automatically. Ensure the instance profile's associated role has the necessary permissions to interact with EKS.
kubeconfig: Typically generated on the instance itself. Theaws eks update-kubeconfigcommand will automatically use the instance's IAM role for authentication.
Frequently Asked Questions
Q: What if I'm using an EC2 instance role to access EKS?
A: Ensure the EC2 instance's IAM role has permissions like eks:DescribeCluster and that this role is mapped in the EKS cluster's aws-auth ConfigMap under mapRoles. aws eks update-kubeconfig run on the EC2 instance will use the instance's role automatically.
Q: How do I check if aws-iam-authenticator or the kubectl-eks plugin is installed and working?
A: For aws-iam-authenticator, run which aws-iam-authenticator and aws-iam-authenticator version. For the kubectl-eks plugin, it's part of the AWS CLI v2; you can test its functionality by running aws eks get-token --cluster-name YOUR_CLUSTER_NAME --region YOUR_REGION.
Q: Can network firewalls cause this "Unauthorized" error?
A: While possible, network issues more typically result in connection refused or timeout errors. An "Unauthorized" error specifically implies the API server received your request but rejected it based on authentication/authorization. However, if an outbound firewall prevents your client from reaching AWS STS or the EKS control plane to generate the token, it could indirectly lead to this error.
Q: My kubeconfig looks correct, my AWS credentials are fine, what else could it be?
A: In this scenario, the aws-auth ConfigMap is almost always the answer. Double-check that your exact IAM user or role ARN is mapped to the correct Kubernetes groups (e.g., system:masters for admin access) in the mapUsers or mapRoles sections of the aws-auth ConfigMap in the kube-system namespace.
Q: Why do I need aws-iam-authenticator or the kubectl-eks plugin if kubectl is already installed?
A: kubectl itself doesn't inherently understand AWS's IAM authentication mechanism. These plugins act as an exec credential provider, dynamically fetching temporary, signed AWS credentials that the EKS API server can validate against IAM, bridging the gap between Kubernetes RBAC and AWS IAM identities.
Related Errors
(none)