Introduction
EKS worker nodes need to authenticate with the cluster and register themselves. When a node fails to join, it shows as "NotReady" or doesn't appear in kubectl get nodes. The node's kubelet can't communicate with the EKS control plane.
Symptoms
Node not appearing:
```bash $ kubectl get nodes
NAME STATUS ROLES AGE VERSION # Empty or missing new node ```
Node status NotReady:
```bash $ kubectl get nodes
NAME STATUS ROLES AGE VERSION ip-10-0-1-100.ec2.internal NotReady <none> 5m v1.28.0 ```
kubelet logs on node:
```bash $ journalctl -u kubelet -f
E0115 10:00:00.000000 kubelet.go:1234] Unable to register node "ip-10-0-1-100.ec2.internal" with API server: Unauthorized ```
EC2 instance console:
```bash $ aws ec2 get-console-output --instance-id i-abc123 --output text | grep -i eks
"Failed to register with cluster: Unauthorized" ```
Common Causes
- 1.aws-auth ConfigMap misconfigured - Node's IAM role not mapped
- 2.Wrong IAM role - Node using different role than configured
- 3.Security group blocking - Node can't reach control plane
- 4.VPC/subnet misconfiguration - Node in wrong network
- 5.Cluster endpoint access - Private endpoint issues
- 6.kubelet version mismatch - Incompatible Kubernetes version
- 7.Node instance profile missing - No IAM profile attached
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check Node IAM Role
```bash # Get instance IAM role aws ec2 describe-instances --instance-ids i-abc123 \ --query 'Reservations[*].Instances[*].IamInstanceProfile.Arn'
# Get the role name from the profile aws iam get-instance-profile --instance-profile-name NODE_PROFILE_NAME \ --query 'InstanceProfile.Roles[*].RoleName'
# Expected format: eks-node-role or similar ```
Step 2: Verify aws-auth ConfigMap
```bash # Get current aws-auth config kubectl get configmap aws-auth -n kube-system -o yaml
# Should contain mapRoles section: # mapRoles: # - rolearn: arn:aws:iam::ACCOUNT:role/eks-node-role # username: system:node:{{EC2PrivateDNSName}} # groups: # - system:bootstrappers # - system:nodes ```
Add missing role mapping:
```bash # Edit the configmap kubectl edit configmap aws-auth -n kube-system
# Add or verify the node role mapping: apiVersion: v1 kind: ConfigMap metadata: name: aws-auth namespace: kube-system data: mapRoles: | - rolearn: arn:aws:iam::ACCOUNT:role/eks-node-role username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes ```
Or apply via kubectl:
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: arn:aws:iam::ACCOUNT:role/eks-node-role
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
EOFStep 3: Check Node Security Group
```bash # Get node's security groups aws ec2 describe-instances --instance-ids i-abc123 \ --query 'Reservations[*].Instances[*].SecurityGroups[*].GroupId'
# Get cluster security group aws eks describe-cluster --name my-cluster \ --query 'cluster.resourcesVpcConfig.clusterSecurityGroupId'
# Node security group must allow: # - Outbound 443 to control plane (or 0.0.0.0/0) # - Inbound from control plane for webhook callbacks ```
Add required rules:
```bash # Allow node to communicate with control plane aws ec2 authorize-security-group-egress \ --group-id sg-node \ --protocol tcp \ --port 443 \ --cidr 0.0.0.0/0
# For private clusters, allow control plane security group aws ec2 authorize-security-group-ingress \ --group-id sg-node \ --protocol tcp \ --port 10250 \ --source-group sg-cluster-control-plane ```
Step 4: Verify Cluster Endpoint Access
```bash # Check cluster endpoint configuration aws eks describe-cluster --name my-cluster \ --query 'cluster.resourcesVpcConfig.{Public:publicAccessCidrs,Private:endpointPrivateAccess,PublicEnabled:endpointPublicAccess}'
# If private endpoint only, node must be in VPC # If public endpoint, node must have internet access ```
For private-only endpoints:
```bash # Ensure node is in correct VPC aws ec2 describe-instances --instance-ids i-abc123 \ --query 'Reservations[*].Instances[*].[VpcId,SubnetId]'
# Compare with cluster VPC aws eks describe-cluster --name my-cluster \ --query 'cluster.resourcesVpcConfig.vpcId' ```
Step 5: Check kubelet Logs on Node
```bash # SSH into the node (via SSM or bastion) aws ssm start-session --target i-abc123
# Check kubelet status sudo systemctl status kubelet
# View kubelet logs sudo journalctl -u kubelet -f --no-pager
# Common errors: # "Unauthorized" -> aws-auth issue # "Connection refused" -> network/endpoint issue # "TLS handshake timeout" -> security group issue ```
Step 6: Verify Node's Bootstrap Script
```bash # Check user data on node aws ec2 describe-instance-attribute --instance-id i-abc123 --attribute userData \ --query 'UserData.Value' --output text | base64 -d
# Should contain EKS bootstrap script with cluster name: #!/bin/bash /etc/eks/bootstrap.sh my-cluster \ --b64-cluster-ca BASE64_CA \ --apiserver-endpoint https://CLUSTER_ENDPOINT ```
For managed node groups, this is automatic. For self-managed, verify bootstrap arguments.
Step 7: Check Kubernetes Version Compatibility
```bash # Get cluster version aws eks describe-cluster --name my-cluster \ --query 'cluster.version'
# Get kubelet version on node kubectl version --short # Or on node: kubelet --version
# Kubernetes version skew policy: # - kubelet can be same version as control plane # - kubelet can be 1 minor version behind # - kubelet cannot be ahead of control plane ```
Step 8: Verify Node Instance Profile
```bash # Check if instance has IAM profile aws ec2 describe-instances --instance-ids i-abc123 \ --query 'Reservations[*].Instances[*].IamInstanceProfile'
# If null, attach profile: aws ec2 associate-iam-instance-profile \ --instance-id i-abc123 \ --iam-instance-profile Name=eks-node-profile
# Node role needs: # - AmazonEKSWorkerNodePolicy # - AmazonEC2ContainerRegistryReadOnly # - AmazonEKS_CNI_Policy ```
Step 9: Test Connectivity to Control Plane
```bash # From the node, test API server connectivity curl -k https://CLUSTER_ENDPOINT/healthz
# Should return "ok"
# Test DNS resolution nslookup CLUSTER_ENDPOINT
# Check if node can reach cluster aws ssm start-session --target i-abc123 curl -v https://CLUSTER_ENDPOINT ```
Step 10: Reboot or Recreate Node
```bash # If all configuration correct, reboot node aws ec2 reboot-instances --instance-ids i-abc123
# Or terminate and let ASG recreate aws ec2 terminate-instances --instance-ids i-abc123
# For managed node groups, update to trigger rollout: aws eks update-nodegroup-version \ --cluster-name my-cluster \ --nodegroup-name my-nodegroup ```
Common aws-auth Errors
| Symptom | Cause | Fix |
|---|---|---|
| Unauthorized | Role not in aws-auth | Add mapRoles entry |
| Forbidden | Wrong groups | Add system:nodes group |
| Cannot connect | Network issue | Check security groups |
| Certificate error | Wrong cluster CA | Verify bootstrap data |
Verification
```bash # Check node status kubectl get nodes
# Should show Ready status NAME STATUS ROLES AGE VERSION ip-10-0-1-100.ec2.internal Ready <none> 1m v1.28.0
# Check node details kubectl describe node ip-10-0-1-100.ec2.internal
# Conditions should show Ready: True ```
Related Issues
- [Fix AWS EKS Cluster Autoscaler Not Scaling](/articles/fix-aws-eks-cluster-autoscaler-not-scaling)
- [Fix AWS EKS Pod Networking Failed](/articles/fix-aws-eks-pod-networking-failed)
- [Fix AWS EKS IAM Role for Service Account](/articles/fix-aws-eks-iam-role-for-service-account)
Related Articles
- [AWS troubleshooting: Fix IAM Permission Denied - Complete Tro](fix-iam-permission-denied)
- [AWS cloud troubleshooting: AWS ACM Certificate Pending Validation Because the](aws-acm-certificate-pending-validation-wrong-route53-zone)
- [AWS cloud troubleshooting: AWS ALB Returns 502 Because the Target Closed the ](aws-alb-502-target-closed-connection-keepalive-timeout-mismatch)
- [AWS cloud troubleshooting: Fix AWS ALB CreateListener TargetGroupNotFound Err](aws-alb-createlistener-targetgroupnotfound)
- [AWS cloud troubleshooting: Fix Aws Alb Lambda 502 Bad Gateway Issue in AWS](aws-alb-lambda-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix AWS EKS Node Not Joining Cluster", "description": "Troubleshoot EKS node joining issues. Fix aws-auth ConfigMap, IAM roles, security groups, and networking configuration.", "url": "https://www.fixwikihub.com/fix-aws-eks-node-not-joining", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-01T17:20:26.839Z", "dateModified": "2026-04-01T17:20:26.839Z" } </script>