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. 1.aws-auth ConfigMap misconfigured - Node's IAM role not mapped
  2. 2.Wrong IAM role - Node using different role than configured
  3. 3.Security group blocking - Node can't reach control plane
  4. 4.VPC/subnet misconfiguration - Node in wrong network
  5. 5.Cluster endpoint access - Private endpoint issues
  6. 6.kubelet version mismatch - Incompatible Kubernetes version
  7. 7.Node instance profile missing - No IAM profile attached

Step-by-Step Fix

  1. 1.Check logs for specific error messages
  2. 2.Verify configuration settings
  3. 3.Test network connectivity
  4. 4.Review recent changes
  5. 5.Apply corrective action
  6. 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:

bash
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
EOF

Step 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

SymptomCauseFix
UnauthorizedRole not in aws-authAdd mapRoles entry
ForbiddenWrong groupsAdd system:nodes group
Cannot connectNetwork issueCheck security groups
Certificate errorWrong cluster CAVerify 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 ```

  • [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)
  • [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>