Generated banner for Hyperpod Node Debugger
Generated logo for Hyperpod Node Debugger

Hyperpod Node Debugger

AWS LabsOfficialPublished by AWS Labs

  • Skill
  • Workflow
  • Cloud and DevOps
  • Apache-2.0
  • Low risk
  • Has scripts

From the author

Diagnose and remediate per-node issues on a HyperPod cluster (EKS or Slurm) — a specific node is unhealthy, unresponsive, stuck, or needs replacing. Covers on-node EFA, GPU / accelerator hardware (XID, ECC, NVLink, row-remap, DCGM), Slurm node down/drained, disk and memory pressure, per-node lifecycle-script failures, SSM agent, container runtime, kernel panics, pod networking. Read-only. Not for cluster-wide provisioning (→ hyperpod-cluster-debugger), NCCL (→ hyperpod-nccl), or MFU (→ hyperpod-mfu-debugger).
— the description by AWS Labs

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The HyperPod Node Debugger provides a structured, read-only diagnostic workflow for identifying and resolving issues on individual nodes within a HyperPod cluster. It covers a wide range of failure modes, including EFA networking, GPU/accelerator hardware faults (XID, ECC, NVLink), Slurm node states, resource exhaustion, and container runtime errors. The skill emphasizes a safe, non-destructive triage process, requiring explicit customer approval for any remediation steps, and includes specific guidance for Infrastructure-as-Code (IaC) environments to prevent configuration drift.

What it does

  • Performs read-only triage of cluster nodes to identify health failures.
  • Maps detected symptoms to specific diagnostic sections for targeted troubleshooting.
  • Provides verified commands for remediation, including rebooting or replacing nodes.
  • Includes safety checks for IaC-managed resources to prevent configuration drift.
  • Supports both EKS and Slurm orchestrators for HyperPod environments.
  • Guides the user through a structured investigate-reboot-replace escalation path.

When to use it

  • When a specific node in a HyperPod cluster is unhealthy, unresponsive, or stuck.
  • When training jobs hang due to suspected hardware or networking issues on a single node.
  • When GPU/accelerator errors (e.g., XID, ECC, NVLink) are suspected.
  • When investigating node-level resource exhaustion (disk, memory, OOM).
  • When Slurm nodes are marked as down or drained unexpectedly.

Advantages

  • Standardizes the diagnostic process for complex HyperPod node failures.
  • Reduces manual effort by automating the collection of cluster and node health signals.
  • Prioritizes safety by enforcing a read-only triage phase before any remediation.
  • Provides clear guidance on when to escalate to AWS Support.
  • Integrates with existing IaC workflows to maintain infrastructure integrity.

Usage examples

“My node i-0123456789abcdef0 is stuck in a Pending state. How do I check it?”
The agent will run the triage script focused on that specific instance ID, identify the failure reason (e.g., lifecycle script or hardware), and provide the corresponding diagnostic steps.
“I suspect a GPU hardware failure on node i-0987654321fedcba0. What should I do?”
The agent will guide you to check for XID or ECC errors using the provided diagnostic commands and, if confirmed, suggest the appropriate batch-reboot or batch-replace procedure.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/awslabs/hyperpod-node-debugger/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip hyperpod-node-debugger.zip -d .agents/skills

Documentation by AWS Labs

HyperPod Node Debugger

Operating policy. Run read-only diagnostics yourself. Never run a command that changes cluster, node, or workload state — present each one as a Suggested command (run this yourself) block and wait for the customer. Destructive order: investigate → reboot → replace (replace destroys root + secondary volumes; not supported on Slurm controller nodes). Never discard training state, logs, or caches on speculation.

IaC note (always include with mutation commands). When you suggest any command that changes cluster, VPC, SG, subnet, or EKS configuration (e.g. authorize-security-group-*, modify-vpc-attribute, update-cluster, kubectl label/cordon/drain, create namespace, set env daemonset), ask the customer first whether the cluster / VPC / SG is managed by Infrastructure-as-Code (CloudFormation, CDK, Terraform, Pulumi). If yes, tell them: "Apply this change in your IaC source first, then deploy through the pipeline — running the command directly will drift from your template and the next stack update may overwrite it." If they need to fix the issue immediately and the IaC change will follow, flag the drift explicitly so they remember to reconcile.

Read-only triage. scripts/triage-cluster.sh (and helpers check-efa-sg.sh, check-node-reachability.sh, check-vpc-config.sh) read state and print each issue as [FAIL] ... → references/node-diagnostics-detail.md § <section>. Catalog of customer-ticket patterns: references/node-issue-catalog.md.


Workflow

  1. Collect cluster name, region, suspect instance ID, exact error string from logs.

  2. Run scripts/triage-cluster.sh (add --node <INSTANCE-ID> to focus one node).

  3. For every [FAIL] / issue entry, Read the referenced section.

  4. Present: what script detected (copy the line verbatim), root cause, exact command(s) with instance/SG IDs filled in, blast radius (e.g. "reboots i-xxx", "wipes volumes on replacement"). For any command that mutates cluster/VPC/SG/EKS state, ask whether the affected resource is IaC-managed and surface the drift warning from the operating-policy note above.

  5. Wait for explicit customer approval. Destructive order: investigate → reboot → replace.

  6. Re-run triage to confirm. Iterate if not cleared.

Step 1: Triage

bash scripts/triage-cluster.sh --cluster <CLUSTER_NAME_OR_ARN> --region <REGION>

# Focus on one node:
bash scripts/triage-cluster.sh --cluster <CLUSTER_NAME_OR_ARN> --region <REGION> --node <INSTANCE_ID>

One pass collects: cluster status + NodeRecovery, events, per-node health (HyperPod + EKS labels, Slurm states), VPC/SG snapshot, CloudWatch availability, SSM readiness, on-node resource checks (disk, memory, /dev/shm, OOM, NVMe, time sync, SSM agent), Slurm node→instance mapping.

Tags: [PASS] passed · [FAIL] issue with a → references/... pointer · [WARN] advisory · [INFO] informational. Priorities: P0 blocks operation · P1 degraded · P2 informational.

Step 2: Match signal → section

Events (list-cluster-events) — provisioning-time:

EventSection
"EFA health checks did not run successfully" (public-doc verbatim signal)A: EFA/SG
Instance bootstrap or network-misconfiguration eventA + B: VPC
Lifecycle-script failure or timeoutD: Lifecycle
Insufficient-capacity or AZ-mismatch failure at creationC: Capacity
Hardware failure / UnschedulablePendingReplacementF: Hardware

EKS labels:

LabelSection
node-health-status: UnschedulablePendingReplacementF
node-health-status: UnschedulablePendingRebootF
deep-health-check-status: FailedG → F

Symptoms:

SymptomSection
Training hangs at NCCL init / AllReduceA → E
Slurm node down / "Node unexpectedly rebooted"H: Slurm
Jobs stuck PENDING / COMPLETINGH
Auto-repair not triggeringF
GPU not visible / XID / ECC errorsG
GPU row-remap pending/failed / silent NaNs / DCGM FailG § G.1.a/b
Disk full / OOM / "Cannot allocate memory"I: Resources
Wrong vCPU count (e.g. 96 instead of 192 on p5.48xlarge)J: Config
Container CrashLoopBackOff / runtime crashM: Container Runtime
aws-node CrashLoopBackOff / gRPC 50051 refusedO: CNI / Pod Networking
Pods stuck Pending with no IP / CNI errorO
DNS resolution / enableDnsSupportB § B.2
Public subnet / IGW misconfiguredB § B.3
Missing VPC endpoints (ECR / STS / FSx)B § B.4
EKS VPC / SG mismatch with HyperPodB § B.5
Kernel panic / watchdog / hung taskN: Kernel
Need shell on a nodeK: SSM
Collect logs for AWS SupportL: Log Collection

A: EFA / Security Group

Per the HyperPod prerequisites doc, the SG must allow all inbound and outbound to itself. scripts/check-efa-sg.sh validates self-ref rules on every cluster SG. On-node EFA check via scripts/check-node-reachability.sh over SSM. Full: § A.

B: VPC / Routing

SG/subnet VPC mismatch, missing S3 Gateway endpoint, EKS auth mode, worker→controller routing, VPC DNS support, private-subnet + NAT / VPC endpoints, EKS↔HyperPod VPC alignment. scripts/check-vpc-config.sh. Full: § B.

C: Capacity / AZ

Insufficient-capacity failure at creation, or no subnets in the AZ where capacity is available. Check AZ offerings via describe-instance-type-offerings, then change subnet AZ or use Flexible Training Plans / ODCR. Full: § C.

D: Lifecycle Scripts

Surfaced in cluster events + CloudWatch under LifecycleConfig/<group>/<instance-id>. Common: S3 connectivity, IAM gaps, CRLF line endings, infinite loops, parameter-name mismatch. Full: § D.

E: Software Versions

Delegate to hyperpod-version-checker to compare NVIDIA driver, CUDA, NCCL, EFA installer, OFI NCCL, PyTorch across nodes. Ensure job env has FI_PROVIDER=efa, FI_EFA_USE_DEVICE_RDMA=1, NCCL_SOCKET_IFNAME=^lo,docker. Full: § E.

F: Hardware / Auto-Repair

Confirm NodeRecovery=Automatic, inspect the EKS health labels + sagemaker.amazonaws.com/fault-details annotation, and read the SagemakerHealthMonitoringAgent/<group>/<instance> CloudWatch stream. HMA runs passive background checks on GPU and Neuron state and reboots the node on count mismatch (per the HMA doc: "if there's a mismatch between the expected number of GPUs … and the count returned by nvidia-smi, then HMA reboots the node"; same for neuron-ls). Manual recovery order: reboot first, replace only if reboot fails; the preferred path is the batch APIs (BatchReboot/BatchReplaceClusterNodes). Full: § F · patterns: node-issue-catalog.md.

G: GPU / Accelerator

NVIDIA (p4d/p5/g5/g6): nvidia-smi + dmesg over SSM for Xid, ECC, thermal throttling. Xid classification per NVIDIA's catalog: 13 Graphics Engine Exception (application-level), 31 GPU memory page fault (application, can be driver/HW), 63 GPU memory remapping event (HW/ECC), 71 CE4 Error (HW copy engine), 74 NVLink Error (HW), 79 GPU has fallen off the bus (PCIe bus), 109 Context Switch Timeout Error (HW). Any uncorrectable ECC → drain and replace. Row-remap state is the authoritative silent-degradation signal (§ G.1.a).

Trainium / Inferentia (trn1/trn2/inf2): Neuron SDK — neuron-ls, neuron-top, neuron-monitor. nvidia-smi does not apply.

GPU / accelerator failures flow into § F for reboot / replace. Full: § G.

H: Slurm Node Management

Node down/unresponsive, unexpected reboots, stuck PENDING/COMPLETING jobs, Slurm-to-instance-ID translation. Primary access is SSM; diagnose slurmd first, fix the root cause, then start/resume the node per § H. Full: § H.

I: Resource Exhaustion

Disk full (HyperPod root volume defaults to 100 GB and is not intended to grow post-creation), OOM, os.fork() memory error, /dev/shm exhaustion, inode exhaustion. Fork-memory fix: export FI_EFA_USE_HUGE_PAGE=0. Redirect bulk data to /opt/sagemaker (secondary EBS) or /opt/dlami/nvme (instance store). Full: § I.

J: Configuration

p5.48xlarge reports 96 vCPU instead of 192 → set ThreadsPerCore=2 via update-cluster. Full: § J.

K: Node Access via SSM

No direct SSH on HyperPod. Target format sagemaker-cluster:<CLUSTER_ID>_<GROUP>-<INSTANCE_ID>. Failures: plugin missing, wrong prefix, IAM, VPC endpoints. Full: § K.

L: Log Collection

Delegate to hyperpod-issue-report for S3-stored bundles. Key CloudWatch streams: LifecycleConfig/<group>/<instance-id>, SagemakerHealthMonitoringAgent/<group>/<instance-id>. Full: § L.

M: Container Runtime

CrashLoopBackOff, OOMKilled, ImagePullBackOff, RunContainerError on EKS. kubectl describe pod + on-node crictl ps -a, journalctl -u containerd. Full: § M.

N: Kernel & System

Kernel panic, watchdog timeout, soft lockup, unexpected reboots not explained by HyperPod health monitoring. dmesg | grep -iE 'panic|watchdog|hung_task|NMI' + journalctl -b -1. nvrm-related signatures point at NVIDIA driver crashes. Full: § N.

O: CNI / Pod Networking

VPC CNI (aws-node) failures, IPAMD errors, gRPC 127.0.0.1:50051 refused, pods stuck Pending with FailedCreatePodSandBox. Script auto-checks aws-node, kube-proxy, CoreDNS. Full: § O.


Prerequisites

  • aws CLI v2, recent enough to support the HyperPod cluster commands (describe-cluster, list-cluster-nodes, batch-reboot-cluster-nodes, batch-replace-cluster-nodes)

  • python3, bash 4+ (associative arrays are required by the scripts)

  • kubectl authenticated to the EKS cluster (K8s checks skipped if absent)

  • session-manager-plugin for on-node hardware checks

  • unbuffer (from the expect package) — optional; if missing, SSM on-node probes are skipped while the rest of the triage still runs. Install via yum install expect / apt install expect.

Defaults

  • Region — required: pass --region or set $AWS_DEFAULT_REGION.

  • Target scope — all nodes; --node <ID> focuses one.

  • Event window — up to 500 most recent events (5 × 100, paginated).

  • Node list cap — up to 20,000 nodes (200 × 100); warns on cap.

  • SSM probes — 180 s per node with retry-on-throttle.

  • Colors — auto-disabled on non-TTY; --no-color to force off.

Error handling

FailureScriptTell the customer
aws sts get-caller-identity failsExit 1"Fix AWS credentials and rerun."
describe-cluster failsExit 1 after listing region's clusters"Confirm cluster name and region."
sagemaker:* / ec2:* / logs:* AccessDeniedWarn, add Missing IAM permission for <API>, continue"Grant the listed IAM action and rerun."
kubectl absent or unauthenticatedSkip K8s checks"Install/authenticate kubectl (see § K)."
session-manager-plugin absentSkip on-node probes"Install session-manager-plugin (see § K)."
SSM start-session fails or times out (180s)Mark node unreachable with → § K pointer"Rerun with --node <ID> to isolate; verify SSM agent on the node."
Cluster > 20,000 nodesFirst 20,000 paginated; warn"Use --node to target specific nodes."

Exit codes: 0 triage complete · 1 cluster not found or fatal prerequisite missing.

IAM permissions

Read-only diagnostic — covers triage-cluster.sh, check-efa-sg.sh, check-vpc-config.sh, and check-node-reachability.sh:

{
  "Action": [
    "sagemaker:DescribeCluster",
    "sagemaker:DescribeClusterNode",
    "sagemaker:ListClusterNodes",
    "sagemaker:ListClusterEvents",
    "sagemaker:ListClusters",
    "eks:DescribeCluster",
    "ec2:DescribeSecurityGroups",
    "ec2:DescribeSubnets",
    "ec2:DescribeVpcs",
    "ec2:DescribeVpcAttribute",
    "ec2:DescribeVpcEndpoints",
    "ec2:DescribeRouteTables",
    "ec2:DescribeNetworkInterfaces",
    "ec2:DescribeInstances",
    "ec2:DescribeInstanceTypeOfferings",
    "ec2:DescribeInstanceTypes",
    "logs:DescribeLogGroups",
    "logs:DescribeLogStreams",
    "logs:FilterLogEvents",
    "ssm:StartSession",
    "ssm:TerminateSession",
    "service-quotas:GetServiceQuota"
  ]
}

sts:GetCallerIdentity is implicit — it requires no IAM action. SSM on HyperPod uses start-session against sagemaker-cluster:<cluster-id>_<group>-<iid> targets — not send-command against bare instance IDs. For remediation commands, grant the matching write permission (e.g. ec2:AuthorizeSecurityGroupIngress / Egress, ec2:RevokeSecurityGroupIngress / Egress, ec2:ModifyVpcAttribute, sagemaker:UpdateCluster, sagemaker:BatchRebootClusterNodes, sagemaker:BatchReplaceClusterNodes). Not needed for the diagnostic itself.

Skill delegation

NeedUse
Cluster creation / deployment failureshyperpod-cluster-debugger (§ A / B / C / H + --validate)
Cluster-wide SSM outagehyperpod-cluster-debugger § F
Single-node SSM failurestay here — § K
Cluster-wide EFA health-check failure at creation timehyperpod-cluster-debugger § A
Single-node EFA failure post-provisioningstay here — § A
NCCL AllReduce / collective-op timeouts (distributed)hyperpod-nccl
Silent GPU NaNs on a specific node (row-remap / DCGM)stay here — § G.1 (even if discovered by NCCL)
Post-deployment cluster-wide managementhyperpod-cluster-debugger
Shell / commands on nodeshyperpod-ssm
CUDA / NCCL / EFA version comparisonhyperpod-version-checker
Diagnostic bundle for AWS Supporthyperpod-issue-report
Training performance / MFU degradationhyperpod-mfu-debugger

Escalate to AWS Support

Escalate when:

  1. SG rules correct and reachability passes but EFA still fails.

  2. VPC correct but K8s bootstrap fails — check VPC flow logs for REJECT.

  3. Hardware failure where replacement keeps failing (bad physical host).

  4. Node replacement fails with an insufficient-capacity signal despite a valid ODCR.

Before opening the case
# 1. Cluster identity + affected node status
aws sagemaker describe-cluster --cluster-name <CLUSTER> --region <REGION>
aws sagemaker list-cluster-nodes --cluster-name <CLUSTER> --region <REGION> \
  --query "ClusterNodeSummaries[?InstanceId=='<INSTANCE_ID>']"

# 2. Triage bundle (scoped to the affected node where possible)
bash scripts/triage-cluster.sh --cluster <CLUSTER> --region <REGION> --node <INSTANCE_ID> > triage.txt

# 3. Per-node log/config bundle to S3 (delegates to hyperpod-issue-report)
#    See skills/hyperpod-issue-report/SKILL.md for the exact invocation.
Include in the case
  • Cluster name + ARN and AWS region

  • Orchestrator (EKS or Slurm)

  • Affected instance IDs / node names / instance-group names

  • Timestamp window (UTC start / end) of the failure

  • Exact error strings observed (copy verbatim from pod logs, CloudWatch, dmesg, events)

  • XID numbers / ECC counts / DCGM output where hardware is implicated

  • triage.txt from step 2 above

  • S3 URI of the hyperpod-issue-report bundle from step 3

Patterns from real customer tickets: node-issue-catalog.md.

Files

references/node-diagnostics-detail.md

Node Diagnostics Detail

Full diagnostic procedures, commands, and fixes for each section referenced from SKILL.md.


A: EFA / Security Group

Signals: "EFA health checks did not run successfully", EFA send/recv timeouts, NCCL connectivity fails.

bash scripts/check-efa-sg.sh --cluster <CLUSTER> --region <REGION>

Required rules on every cluster SG (per the HyperPod prerequisites doc — "configure the security group to allow all inbound and outbound traffic to and from the security group itself"):

  1. Outbound self-ref (all protocols, source = SG) — required for EFA.

  2. Inbound self-ref (all protocols, source = SG) — required for node-to-node communication.

Do not add 0.0.0.0/0 outbound to the EFA security group. Per the HyperPod prerequisites doc: "avoid using 0.0.0.0/0 for outbound rules, as this may cause EFA health check failures." Outbound internet traffic for AWS API calls, package downloads, and image pulls must be routed at the subnet level — via a NAT gateway in private subnets, or via VPC interface/gateway endpoints in air-gapped VPCs (see § B.4).

The script prints [PASS] / [FAIL] per rule.

Suggested command — add EFA SG self-referencing rules (run this yourself)

Preconditions: the rule check above (scripts/check-efa-sg.sh) reports [FAIL] on inbound or outbound self-ref for <SG_ID>; <SG_ID> is one of the security groups attached to the HyperPod cluster (describe-cluster → VpcConfig.SecurityGroupIds); apply once per SG if multiple are attached; for IaC-managed SGs, see the operating-policy IaC note in SKILL.md before running directly.

Command:

aws ec2 authorize-security-group-egress --group-id <SG_ID> --region <REGION> \
  --ip-permissions '[{"IpProtocol":"-1","UserIdGroupPairs":[{"GroupId":"<SG_ID>","Description":"HyperPod EFA intra-SG"}]}]'

aws ec2 authorize-security-group-ingress --group-id <SG_ID> --region <REGION> \
  --ip-permissions '[{"IpProtocol":"-1","UserIdGroupPairs":[{"GroupId":"<SG_ID>","Description":"HyperPod intra-SG"}]}]'

Blast radius: opens all protocols between instances that share this SG (intended scope for intra-cluster EFA traffic) — does not open anything to the internet or to other SGs. Idempotent: InvalidPermission.Duplicate = the rule already exists. Reversible with revoke-security-group-ingress/revoke-security-group-egress using the same --ip-permissions payload. For outbound internet access, route at the subnet level (NAT gateway or VPC endpoints) — not via a 0.0.0.0/0 rule on this SG (per HyperPod prerequisites).

For provisioned nodes with EFA problems, use the hyperpod-ssm skill to upload and run check-node-reachability.sh, or spot-check:

bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target <TARGET> --region <REGION> 'fi_info -p efa'

B: VPC / Routing

Signals: "bootstrap failed...network misconfiguration", S3 timeout, subnet/VPC mismatch, DNS resolution failure, node unreachable despite correct SG.

bash scripts/check-vpc-config.sh --cluster <CLUSTER> --region <REGION>
B.1 Common errors
ErrorFix (each is a mutation — see Suggested-command blocks below or in the referenced section)
SG and subnet in different VPCsMove SG to same VPC as subnet
S3 timeout (endpoint unreachable from private subnet)Add an S3 Gateway VPC endpoint — see hyperpod-cluster-debugger § lifecycle-scripts for the Suggested-command block
EKS auth mode is CONFIG_MAP onlyAccess entries require API or API_AND_CONFIG_MAP; switching the auth mode is a cluster-level change — see the EKS access-entries docs and hyperpod-cluster-debugger § D
aws-hyperpod namespace missingkubectl create namespace aws-hyperpod — customer-run. Preconditions: namespace is genuinely missing (not just RBAC denial). Blast radius: creates a new namespace; low risk, but confirm which namespace HyperPod expects on this cluster version
Workers can't reach EKS controllerAdd route to EKS VPC CIDR in worker subnet; check VPC flow logs
B.2 VPC DNS

HyperPod requires both enableDnsSupport and enableDnsHostnames on the VPC. Without these, EKS internal DNS, internal hostnames, and ip-x-x-x-x Slurm nodenames fail to resolve.

Diagnose (read-only):

aws ec2 describe-vpc-attribute --vpc-id <VPC> --attribute enableDnsSupport   --region <R> --query 'EnableDnsSupport.Value'
aws ec2 describe-vpc-attribute --vpc-id <VPC> --attribute enableDnsHostnames --region <R> --query 'EnableDnsHostnames.Value'
Suggested command — enable VPC DNS attributes (run this yourself)

Preconditions: VPC is customer-owned in this account (cannot modify attributes on a VPC shared from another account via RAM); current values are false (verify with the read-only describe-vpc-attribute calls above — calling modify on already-enabled attributes is a harmless no-op but wastes a call); change is acceptable cluster-wide (every instance in the VPC gains Amazon DNS resolution and internal hostnames).

Command:

aws ec2 modify-vpc-attribute --vpc-id <VPC> --region <R> --enable-dns-support '{"Value":true}'
aws ec2 modify-vpc-attribute --vpc-id <VPC> --region <R> --enable-dns-hostnames '{"Value":true}'

Blast radius: additive — enables Amazon-provided DNS resolution and ip-x-x-x-x internal hostnames for every existing and future instance in this VPC. Does not affect existing IPs, routes, or SGs. Reversible by setting the values to false, but disabling on a live HyperPod cluster will break EKS internal DNS and Slurm nodename resolution.

B.3 Private subnets

HyperPod subnets should be private — route tables should not have a direct default route to an IGW. If outbound internet is needed, route 0.0.0.0/0 via a NAT Gateway in a separate public subnet. In air-gapped VPCs, the default route can be absent and outbound goes through VPC endpoints (§ B.4).

aws ec2 describe-route-tables \
  --filters "Name=association.subnet-id,Values=<subnet-1>,<subnet-2>" \
  --region <R> \
  --query "RouteTables[*].{Assoc:Associations[?SubnetId!=\`null\`].SubnetId,Routes:Routes[?DestinationCidrBlock==\`0.0.0.0/0\`]}" \
  --output json
Route target for 0.0.0.0/0Subnet typeAction
igw-*Public — not supportedRemove IGW route; use a NAT Gateway
nat-*Private with internet egressOK
AbsentFully private / air-gappedOK if VPC endpoints are configured — see § B.4
vpce-*Endpoint-only routingOK
B.4 VPC endpoints (internet-disabled VPCs)

When there is no NAT Gateway, nodes need private interface endpoints for every AWS service they call. Interface endpoints listen on TCP/443 — the endpoint's SG must allow inbound 443 from the HyperPod subnet CIDR.

EndpointTypeRequiredPurpose
com.amazonaws.<region>.s3GatewayYesLifecycle scripts, DLC image layers
com.amazonaws.<region>.ecr.apiInterfaceYesECR authentication
com.amazonaws.<region>.ecr.dkrInterfaceYesPull container images
com.amazonaws.<region>.stsInterfaceYesSTS calls (AssumeRole, GetCallerIdentity)
com.amazonaws.<region>.ssmInterfaceYesSSM Session Manager
com.amazonaws.<region>.ssmmessagesInterfaceYesSSM session traffic
com.amazonaws.<region>.ec2messagesInterfaceYesSSM heartbeats
com.amazonaws.<region>.ec2InterfaceYesEC2 control-plane API (DescribeInstances, EBS volume operations) — instance metadata is link-local (169.254.169.254) and does not use this endpoint
com.amazonaws.<region>.sagemaker.apiInterfaceYesHyperPod control plane
com.amazonaws.<region>.sagemaker.runtimeInterfaceYesRuntime calls
com.amazonaws.<region>.logsInterfaceYesCloudWatch lifecycle + health-monitoring-agent logs
com.amazonaws.<region>.eksInterfaceEKS onlyRequired if EKS endpoint is private-only
com.amazonaws.<region>.fsxInterfaceIf using FSxRequired for FSx for Lustre / OpenZFS
B.5 EKS ↔ HyperPod VPC alignment

When orchestrator is EKS, the EKS cluster and the HyperPod cluster must share a VPC. The SG attached to the HyperPod cluster must either be attached to the EKS cluster itself OR the EKS cluster SG must allow inbound from the HyperPod SG.

Diagnose (read-only):

aws sagemaker describe-cluster --cluster-name <HP>  --region <R> --query 'VpcConfig.{Subnets:Subnets,SGs:SecurityGroupIds}'
aws eks describe-cluster       --name         <EKS> --region <R> --query 'cluster.resourcesVpcConfig.{VPC:vpcId,SGs:securityGroupIds,ClusterSG:clusterSecurityGroupId}'
Suggested command — allow HyperPod SG inbound on the EKS cluster SG (run this yourself)

Preconditions: the orchestrator is EKS and the HyperPod cluster is in the same VPC as the EKS cluster (verify with the read-only describe-cluster calls above); <EKS_CLUSTER_SG> is the EKS-managed cluster SG (clusterSecurityGroupId from eks describe-cluster), not a worker SG; <HP_SG> is one of the security groups attached to the HyperPod cluster (VpcConfig.SecurityGroupIds); the customer prefers the SG-allow approach over re-attaching the HyperPod SG directly to the EKS cluster (both are valid; this rule is needed only when they're not attached).

Command:

aws ec2 authorize-security-group-ingress --group-id <EKS_CLUSTER_SG> --region <R> \
  --ip-permissions "[{\"IpProtocol\":\"-1\",\"UserIdGroupPairs\":[{\"GroupId\":\"<HP_SG>\",\"Description\":\"HyperPod worker traffic\"}]}]"

Blast radius: opens all protocols from every ENI using <HP_SG> to the EKS control-plane SG — scoped to two SGs, not the world. Idempotent: returns InvalidPermission.Duplicate if the rule already exists. Reversible with revoke-security-group-ingress and the same --ip-permissions payload.


C: Capacity / AZ

Signals: insufficient-capacity or AZ-mismatch failure at creation or replacement time.

aws ec2 describe-instance-type-offerings \
  --location-type availability-zone \
  --filters "Name=instance-type,Values=<INSTANCE_TYPE>" \
  --region <REGION> --query 'InstanceTypeOfferings[*].Location'

Fix: add subnet in the AZ where capacity exists, or use Flexible Training Plans / ODCR.


D: Lifecycle Scripts

Signals: "Lifecycle scripts did not run successfully" or "timed out" in events.

CLUSTER_NAME="<C>"
REGION="<R>"
CLUSTER_ID=$(aws sagemaker describe-cluster --cluster-name "$CLUSTER_NAME" --region "$REGION" \
  --query 'ClusterArn' --output text | cut -d/ -f2)
LOG_GROUP="/aws/sagemaker/Clusters/${CLUSTER_NAME}/${CLUSTER_ID}"
aws logs describe-log-streams --log-group-name "$LOG_GROUP" --region "$REGION" \
  --query 'logStreams[?starts_with(logStreamName,`LifecycleConfig`)].logStreamName' --output table

On-node:

bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target <TARGET> --region <REGION> \
  'cat /var/log/provision/provisioning.log'
Log errorFix
Connect timeout on endpoint URL: s3://Add S3 VPC Gateway endpoint
AccessDenied on S3Add s3:GetObject + s3:ListBucket to execution role
Script never exitsAdd proper exit; check infinite loops; test script locally
CRLF line terminatorsdos2unix script.sh before uploading
provisioning_parameters.json mismatchInstance group names must match between script and API

E: Software Versions

Signals: NCCL hangs after node replacement, training fails after AMI update, version drift across nodes.

Delegate to hyperpod-version-checker — compares NVIDIA driver, CUDA, NCCL, EFA installer, OFI NCCL, PyTorch across all nodes.

Quick spot-check on a node (via hyperpod-ssm)
bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target <TARGET> --region <REGION> \
  'nvidia-smi --query-gpu=driver_version --format=csv,noheader && \
   nvcc --version | grep "release" && \
   head -3 /opt/amazon/efa_installed_packages && \
   python3 -c "import torch; print(torch.__version__, torch.version.cuda)"'
CUDA driver vs nvcc toolkit

The CUDA driver (nvidia-smi) and the CUDA toolkit / nvcc (nvcc --version) must be a supported pair — a newer toolkit cannot target an older driver. Mismatch commonly causes CUDA error: no kernel image is available for execution on the device or kernel-launch segfaults.

nvidia-smi | grep "CUDA Version"         # max CUDA the driver supports
nvcc --version | grep "release"          # installed toolkit

Compatibility matrix: see the NVIDIA CUDA Toolkit Release Notes for the toolkit version in use.

EFA / NCCL / libfabric

EFA installer version and AWS OFI NCCL version must be paired per the EFA changelog:

cat /opt/amazon/efa_installed_packages | head -10
fi_info -p efa | head -5

Compatibility matrix: see the AWS EFA installer changelog for the version in use.

Container vs host mismatches

If training works on the host but fails in the container (or vice versa), the cause is almost always one of:

  1. EFA libraries not mounted into the container — container must see /opt/amazon/efa, /opt/amazon/openmpi, and /dev/infiniband. Without these NCCL silently falls back to TCP.

  2. LD_LIBRARY_PATH missing EFA / CUDA paths inside the container:

    export LD_LIBRARY_PATH=/opt/amazon/efa/lib:/opt/amazon/openmpi/lib:/usr/local/cuda/lib64:$LD_LIBRARY_PATH
  3. PyTorch / TF built against a different CUDA major than the host driver supports — rebuild from a base image whose CUDA matches the host (e.g. AWS DLC pytorch-training:<ver>-gpu-py<ver>-cu<host-major>-ubuntu*).

After a driver upgrade, CUDA devices may fail to init until the node is rebooted. Use batch-reboot-cluster-nodes (§ F) and re-run training.

Required job-launcher env vars

Per the EC2 EFA-with-NCCL guide: FI_EFA_USE_DEVICE_RDMA=1 (RDMA-capable instances). For NCCL over EFA, also set FI_PROVIDER=efa and NCCL_SOCKET_IFNAME=^lo,docker to keep NCCL's bootstrap off the loopback / docker interfaces. NCCL_TIMEOUT (seconds) is not AWS-prescribed — tune to your job's longest expected collective if jobs trip the default; otherwise leave unset.

Validation

For PyTorch environment and EFA / network-stack validation, use the AWS-published validation guides for SageMaker HyperPod (available from the AWS SageMaker HyperPod documentation).


F: Hardware / Auto-Repair

Signals: hardware failure event, EKS label UnschedulablePendingReplacement, XID errors, auto-repair not triggering.

# NodeRecovery on each group
aws sagemaker describe-cluster --cluster-name <C> --region <R> \
  --query 'InstanceGroups[*].{Group:InstanceGroupName,Recovery:NodeRecovery}'

# EKS: all node repair labels at once
kubectl get nodes -o custom-columns='NODE:.metadata.name,HEALTH:.metadata.labels.sagemaker\.amazonaws\.com/node-health-status,FAULT:.metadata.labels.sagemaker\.amazonaws\.com/fault-types'

# Repair events — ListClusterEvents returns `Events[*]` with field `Description`
aws sagemaker list-cluster-events --cluster-name <C> --region <R> \
  --query 'Events[?contains(Description,`replacement`) || contains(Description,`reboot`) || contains(Description,`hardware`)]' \
  --output table

# Slurm: HMA auto-recovery is triggered by the health-monitoring agent (not the Slurm reason).
# The Slurm "Action:Reboot" / "Action:Replace" reason is the manual-recovery path — a user sets
# it to ask HyperPod to reboot/replace the node. See "Manually mark a node..." below.
sinfo -o "%N %T %30E"
Suggested command — batch-reboot (run this yourself, soft recovery first)

Preconditions:

  • Fault is plausibly transient (deep-health-check failure, driver hang, stuck process) and reboot may clear it. For confirmed hardware faults (uncorrectable ECC, GPU off-bus, NVLink), skip to batch-replace below.

  • Each node ID belongs to this cluster (verify with list-cluster-nodes).

  • Workload on the node can tolerate a restart — training processes on the node are interrupted.

  • On Slurm: rebooting will not disrupt critical cluster operations (per the API doc note); prefer to drain the node first via scontrol update state=drain to avoid the "Node unexpectedly rebooted" flag (§ H).

  • NodeIds batch size: 1–25 per call (API limit).

Command:

aws sagemaker batch-reboot-cluster-nodes --cluster-name <C> --region <R> --node-ids '["<ID>"]'

Blast radius: per the API doc, "performs a graceful reboot… by calling the Amazon EC2 RebootInstances API." Preserves instance identity, root volume, and secondary volumes — no data loss. Training processes on the node are interrupted; pods on EKS are evicted by kubelet during the restart and rescheduled by the workload controller after the node returns Ready. Recovery time depends on instance type, AMI boot time, and any post-boot lifecycle work.

Suggested command — batch-replace (run this yourself, only if reboot did not clear the fault)

Preconditions:

  • Reboot attempted first and did not clear the fault.

  • Hardware fault confirmed (uncorrectable ECC, GPU bus / NVLink errors, EFA hardware failure); not a software or config issue.

  • Data on root + secondary volumes is backed up to S3 or FSx — per the API doc: "Replacing nodes destroys all instance volumes, including both root and secondary volumes. All data stored on these volumes will be permanently lost and cannot be recovered."

  • Target is NOT a Slurm controller node — per the API doc: "For SageMaker HyperPod clusters using the Slurm workload manager, you cannot replace instances that are configured as Slurm controller nodes."

  • Cluster has been patched via UpdateClusterSoftware — per the API doc: "If you want to invoke this API on an existing cluster, you'll first need to patch the cluster by running the UpdateClusterSoftware API."

  • NodeIds batch size: 1–25 per call (API limit).

Command:

aws sagemaker batch-replace-cluster-nodes --cluster-name <C> --region <R> --node-ids '["<ID>"]'

Blast radius: destroys root + secondary volumes on the replaced instance (permanent data loss). New hardware is provisioned with the same AMI and instance configuration.

Karpenter note: Karpenter's documented design provisions nodes from pending/unschedulable pods (see Karpenter docs on disruption/provisioning), not as a one-for-one node replacement service. So on Karpenter-managed clusters, BatchReplaceClusterNodes terminates the node but does not by itself guarantee a Karpenter-launched replacement — Karpenter creates a new node only if pods become unschedulable on remaining capacity. If you need a guaranteed replacement, ensure workload configuration (pod anti-affinity, resource requests) forces pods to a new node.

Common blockers: NodeRecovery=None (enable it), health agent hasn't detected yet (check SagemakerHealthMonitoringAgent/<group>/<instance> stream), lifecycle script failing on replacement (check LifecycleConfig stream), insufficient capacity, cluster not InService.

HMA detection events

The Health Monitoring Agent emits HealthMonitoringAgentDetectionEvent records to CloudWatch. Use these to read fault history before triggering a manual replace.

CLUSTER_ID=$(aws sagemaker describe-cluster --cluster-name <C> --region <R> \
  --query 'ClusterArn' --output text | cut -d/ -f2)

aws logs filter-log-events \
  --log-group-name "/aws/sagemaker/Clusters/<C>/${CLUSTER_ID}" \
  --log-stream-name-prefix "SagemakerHealthMonitoringAgent/" \
  --filter-pattern 'HealthMonitoringAgentDetectionEvent' \
  --region <R> \
  --query 'events[*].[timestamp,logStreamName,message]' --output table

Reference: the SageMaker HyperPod EKS Health Monitoring Agent documentation.

Repeat-Xid analysis

A hardware-caused Xid will recur after each reboot because reboot does not repair hardware. If you see the same Xid on the same instance more than once, the node almost certainly needs to be replaced rather than rebooted again.

Count Xid occurrences per instance from the HMA detection stream in the customer-visible cluster log group:

# Log group: /aws/sagemaker/Clusters/<CLUSTER>/<CLUSTER_ID>
# Stream prefix: SagemakerHealthMonitoringAgent/
fields @timestamp, @logStream, @message
| parse @message /Xid.*?:\s*(?<xidCode>\d+)/
| filter @message like /HealthMonitoringAgentDetectionEvent/ and @message like /Xid/
| stats count(*) as errorCount,
        earliest(@timestamp) as firstError,
        latest(@timestamp) as lastError
  by @logStream, xidCode, bin(1h) as hourBin
| sort hourBin desc, errorCount desc

A recurring same-Xid + same-instance row is the signal to replace rather than reboot. The exact recurrence threshold is operator choice — many teams use ≥ 2 within a single time window as the trigger.

Node-level fault details (EKS)

When HMA detects a fault it writes a four-part response onto the node (per the HyperPod HMA documentation):

  • Labels: sagemaker.amazonaws.com/node-health-status, sagemaker.amazonaws.com/fault-types, sagemaker.amazonaws.com/fault-reasons

  • Taint: sagemaker.amazonaws.com/node-health-status=Unschedulable:NoSchedule

  • Annotation: sagemaker.amazonaws.com/fault-details — JSON array recording recent faults with timestamps; check the HyperPod HMA doc for the current retention limit

  • Condition (per the HMA doc): Type = fault type, Status = True, Reason = fault reason, LastTransitionTime = fault occurrence time. After a successful recovery the condition status flips back to False.

kubectl get node <NODE> -o jsonpath='{.metadata.annotations.sagemaker\.amazonaws\.com/fault-details}' | jq
kubectl get node <NODE> -o jsonpath='{.status.conditions}' | jq '.[] | select(.type|contains("GPU"))'
Manually trigger reboot or replace on EKS (kubectl label)

If HMA has not detected a fault but the customer has independent evidence, a label can trigger the existing HyperPod recovery path.

Suggested command — trigger replace on EKS (run this yourself)

Preconditions: NodeRecovery=Automatic on the instance group; hardware fault confirmed on <NODE> (not a software/config issue); data on root + secondary volumes is backed up; cluster has been patched via UpdateClusterSoftware if this is the first replace on an existing cluster. Per the HyperPod EKS manual-recovery doc, the preferred path is the Reboot/Replace APIs (BatchReplaceClusterNodes); labelling is an alternative that activates the same recovery process.

Command:

kubectl label nodes <NODE> sagemaker.amazonaws.com/node-health-status=UnschedulablePendingReplacement

Blast radius: marks the node for replacement. Destroys root + secondary volumes on the replaced instance — all data on those volumes is lost. New hardware is provisioned with the same AMI.

Suggested command — trigger reboot on EKS (run this yourself)

Preconditions: NodeRecovery=Automatic on the instance group; fault is plausibly transient (deep-health-check failure, driver hang) and reboot may clear it; workload can tolerate restart.

Command:

kubectl label nodes <NODE> sagemaker.amazonaws.com/node-health-status=UnschedulablePendingReboot

Blast radius: soft recovery — preserves identity, root volume, and secondary volumes. Training processes on the node are interrupted.

Suggested command — manually trigger recovery on Slurm (run this yourself)

Per the HyperPod Slurm manual-recovery doc, the preferred path is the batch APIs (BatchReboot/BatchReplaceClusterNodes) — the scontrol commands below are documented as a legacy alternative that requires direct Slurm-controller access. Both paths activate the same HyperPod recovery processes.

Preconditions: Slurm orchestrator; scontrol run on the controller via SSM; customer has decided between reboot (transient fault) and replace (confirmed hardware fault); replace target is NOT a Slurm controller node; data backed up for replace; cluster has been patched via UpdateClusterSoftware if invoking replace on an existing cluster.

Command:

# Reboot — soft recovery:
scontrol update node=<ip-ipv4> state=fail reason="Action:Reboot"

# Replace — destroys root + secondary volumes:
scontrol update node=<ip-ipv4> state=fail reason="Action:Replace"

Per the HyperPod Slurm manual-recovery doc: for Action:Replace the node goes into fail, waits for running jobs to finish, then is replaced with a fresh instance using the same host name. For either command, do not change the node state or restart slurmctld while recovery is in progress — this can leave the node stuck.

Last-resort force — if the node is stuck in fail, the HyperPod Slurm manual-recovery doc provides scontrol update node=<ip-ipv4> state=down reason="Action:Replace" as a last resort. Per the doc: "this requires administrator privileges (sudo permissions)" and (warning) "it forces kill all jobs, and you might lose all unsaved work." Confirm with the customer that lost in-flight work is acceptable before running.

Blast radius: drains the named node. Action:Replace inherits the same blast radius as batch-replace-cluster-nodes (root + secondary volumes destroyed). state=down additionally force-kills running jobs.

Suggested command — force-delete a stuck Terminating pod (last resort; run this yourself)

Preconditions: pod has been in Terminating state on <NODE> for >30 minutes; the node is quarantined (cordoned, fault confirmed); customer has approved the forced deletion; you understand the API server will remove the pod object immediately even if the container is still running on the node.

Command:

kubectl cordon <NODE>
kubectl delete pods <POD> --grace-period=0 --force

Blast radius: --grace-period=0 --force removes the pod from the API without waiting for kubelet to confirm termination — the container may continue running on the node until the node is rebooted or replaced. Only appropriate when the node will be rebooted/replaced afterward. For a healthy node, use the default kubectl delete pod and let the grace period elapse.


G: GPU/Accelerator

Signals: GPU off bus, deep-health-check-status: Failed, XID errors, low utilization, ECC errors, thermal throttling, NeuronCore errors.

G.1: NVIDIA (p4d/p5/g5/g6)

Run on the affected node via hyperpod-ssm:

bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target <TARGET> --region <REGION> \
  'nvidia-smi -L && nvidia-smi --query-gpu=index,name,utilization.gpu,memory.used,memory.total,temperature.gpu,power.draw,ecc.errors.uncorrected.volatile.total --format=csv && nvidia-smi -q | grep -E "Xid|Error Type|ECC" && dmesg | grep -i "xid\|nvrm\|pcie\|error" | tail -20'

ECC: any uncorrectable error (UCE) → drain and replace. Correctable errors are background noise individually but a growing rate across many GPUs is worth escalating. For detailed GPU diagnostics (NVLink, dmon, XID codes), see node-issue-catalog.md § 2.

Xid reference (per NVIDIA Xid error catalog): common Xid numbers seen in HyperPod dmesg / HMA fault-details:

XidNVIDIA nameClassTypical cause
13Graphics Engine ExceptionAppUser-application fault (out-of-bounds, illegal instruction / register)
31GPU memory page faultAppIllegal address access by a chip unit (usually an application bug; occasionally driver or HW)
63GPU memory remapping eventHWECC memory event; on Ampere+ provides row-remapper detail (see § G.1.a for row-remap triage)
71CE4 ErrorHWCopy Engine 4 exception (seen in HMA example detection logs on HyperPod p-family instances)
74NVLINK ErrorHWNVLink connectivity issue between GPUs / NVSwitch
79GPU has fallen off the busBusDriver cannot reach GPU over PCIe — failing link or GPU (drain + replace)
109Context Switch Timeout ErrorHWTimeout during GPU context switch

For an App-classified Xid (13, 31), investigate the workload before replacing hardware; HMA will reboot on the fault but a software cause will recur until the workload is fixed.

G.1.a Row-remap state (silent memory degradation)

Row-remapping is the mechanism that permanently reassigns physical memory rows around defects on H100 / A100 GPUs. The remap state is the most reliable signal of silent memory degradation — accuracy regressions, sporadic NaNs, and intermittent NCCL hangs that no XID or ECC count explains.

nvidia-smi --query-remapped-rows=gpu_bus_id,remapped_rows.correctable,remapped_rows.uncorrectable,remapped_rows.pending,remapped_rows.failure \
  --format=csv
StateMeaningAction
pending = 0, failure = NoHealthyNone
pending > 0Remap staged but needs a GPU reset / reboot to take effectReboot via batch-reboot-cluster-nodes (§ F); recheck — pending should reach 0
pending > 0 persists after rebootRemap stuck "pending" — memory is silently degradingDrain and replace via batch-replace-cluster-nodes (§ F); escalate to AWS Support
failure = YesRemap capacity exceededDrain and replace (§ F)

uncorrectable > 0 with pending = 0 means historical rows that have already been remapped — fine going forward, but a high count is a warning sign for the hardware cohort.

G.1.b DCGM health and nvvs logs

HyperPod runs DCGM as part of the deep-health-check. Findings are under /var/log/nvidia-dcgm/.

dcgmi health --check -j

ls -1t /var/log/nvidia-dcgm/ | head
tail -n 200 "$(ls -1t /var/log/nvidia-dcgm/nvvs*.log | head -1)"

Treat only Fail / Warn verdicts as authoritative. For comprehensive data collection before opening a ticket:

sudo nvidia-bug-report.sh                                    # NVIDIA's authoritative bundle
sudo tar -czf /tmp/nvidia-dcgm-logs.tgz /var/log/nvidia-dcgm/

Attach both to the AWS Support case along with the triage script output.

G.2: AWS Trainium / Inferentia (trn1/trn2/inf2)

These use the AWS Neuron SDK, not CUDA. nvidia-smi will not work.

Quick health check (via SSM):

bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target <TARGET> --region <REGION> \
  'neuron-ls && neuron-top -n 1 2>/dev/null || echo "neuron-top not available" && dmesg | grep -i "neuron\|nrt\|error" | tail -20'
CommandShows
neuron-lsLists all NeuronCore devices, count, status
neuron-topLive utilization (NeuronCore %, memory, model loaded)
neuron-monitorJSON metrics stream
dmesg | grep -i neuronKernel-level Neuron errors
systemctl status neuron-rtdNeuron Runtime daemon (older AMIs; deprecated in SDK ≥ 2.10)
pip show neuronx-ccNeuron Compiler version
pip show torch-neuronxPyTorch Neuron version

Per-chip counts (AWS Neuron architecture docs):

ChipCores per chip
Trainium1 (NeuronCore-v2)2
Inferentia2 (NeuronCore-v2)2

Trainium2 uses NeuronCore-v3, with a different per-chip core count and HBM topology than the v2 chips above; check the AWS Neuron Trainium2 architecture doc and neuron-ls on the node for the authoritative numbers.

For the chip count per instance type (NeuronDevices × per-chip cores = total), use neuron-ls on the node as the source of truth; the AWS EC2 Trn1 / Trn2 / Inf2 instance-types docs are the authoritative reference if you need a number before node-access is available. Per the HyperPod HMA doc: "Neuron Device Count validation — if there's a mismatch between the actual number of neuron device count in a particular instance type and the count returned by neuron-ls, then HMA reboots the node." Replacement only happens if reboots fail to clear the fault.

Common issues:

SymptomLikely causeAction
neuron-ls shows 0 devicesNeuron kernel driver not loadedCheck lsmod | grep neuron; if the module is absent, the AMI is missing the Neuron driver — use the AWS Neuron DLAMI or rebuild the AMI with Neuron support (loading kernel modules on a running cluster node is a mutation; do not attempt in-place)
neuron-ls: command not foundNeuron SDK not installedInstall from the AWS Neuron repo, or use the AWS Neuron DLAMI
NeuronCore count < expectedDevice failure / driver issue / partial detectionReboot the node (§ F). If the count is still low, replace.
NRT_UNRECOVERABLE_ERROR in dmesg or logsUnrecoverable NeuronDevice faultDrain and replace (§ F). Do not attempt software-only recovery.
OOM on NeuronDevice (HBM exhaustion)Model + activations + optimizer exceed HBMIncrease tensor-parallel degree, enable activation checkpointing, or scale up
Version mismatch across nodesAMI drift after partial replacementPin Neuron package versions in the lifecycle script so replacements converge
Accelerator failure → Section F

Drain the node, then follow the reboot / replace Suggested-command blocks in § F.

Suggested command — drain the node before reboot/replace (run this yourself)

Preconditions: accelerator failure confirmed on <node-name> (GPU off-bus, uncorrectable ECC, NeuronDevice NRT_UNRECOVERABLE_ERROR); customer accepts that pods using emptyDir volumes on this node will lose that data when evicted (EKS path); on Slurm, customer accepts that no new jobs will be scheduled to the node until state=resume runs after recovery; you understand drain is preparation for reboot/replace, not a fix on its own.

Command:

# EKS — cordon prevents new pods; drain evicts existing pods (emptyDir data lost).
kubectl cordon <node-name>
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# Slurm — on the controller via SSM. Running jobs continue until they finish; no new jobs are scheduled.
scontrol update nodename=<node-name> state=drain reason="Accelerator failure -- replacing"

Blast radius: EKS — --delete-emptydir-data discards any in-pod scratch in emptyDir volumes (training caches, ephemeral checkpoints not persisted to PVC//opt/sagemaker); pods are rescheduled elsewhere if capacity exists, otherwise stay Pending. Slurm — running jobs finish on the node; pending jobs route around it. Drain is reversible (kubectl uncordon / scontrol update state=resume) only if you decide not to proceed with reboot/replace.


H: Slurm Node Management

Signals: Node down, "Node unexpectedly rebooted", jobs stuck PENDING/COMPLETING, scontrol ping fails.

Node down / unresponsive
sinfo -o "%N %T %30E"          # state + reason
scontrol show node <NODE>      # full details

# Connectivity checks
ping <node-ip>
ssh <node-name>
srun -w <node-name> hostname

Diagnose (read-only):

bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target <TARGET> --region <REGION> \
  'sudo systemctl status slurmd && free -h && df -h'
Suggested command — bring the node back in Slurm (run this yourself)

Preconditions: root cause of the original slurmd failure has been identified and resolved (disk full, OOM, config parse error) — running start on a node whose underlying issue is unfixed will stop again immediately; node passes a basic health probe (free -h, df -h /, df -h /opt/sagemaker); customer accepts that pending jobs may schedule onto this node immediately after state=resume; do not run systemctl enable slurmd if the unit was deliberately disabled by an admin (verify it was an unexpected reboot, not a config choice).

Command:

# 1. On the affected node — start (and enable, if an unexpected reboot just
#    knocked the unit out of auto-start):
sudo systemctl start slurmd
sudo systemctl enable slurmd   # only if it was not enabled before

# 2. On the Slurm controller — return the node to the idle pool:
scontrol update nodename=<N> state=resume

Blast radius: node returns to idle and pending jobs may schedule immediately. enable makes the unit auto-start on boot — if the unit was previously disabled by lifecycle script or admin, this changes that policy on this node only. Reversible: scontrol update state=drain to take it back out of scheduling, systemctl disable slurmd to revert auto-start. If start+resume does not hold (slurmd dies or node rejoins as down), escalate to batch-reboot then batch-replace (§ F).

Before any intentional reboot of a Slurm compute node, set scontrol update state=drain first and state=resume after — this avoids Slurm flagging the node as unexpectedly rebooted.

Jobs stuck PENDING / COMPLETING → restart slurmctld

When: PENDING with Reason=Resources despite free nodes, GRES miscalculation, COMPLETING after replacement, scontrol ping fails.

Suggested command — restart slurmctld (run this yourself)

Preconditions: restart is targeting a specific known cause that an in-memory restart fixes (cached COMPLETING state after replacement, GRES miscalculation, scheduler not recomputing after node moves); the underlying cluster config is intact — slurm.conf parses cleanly (scontrol show config >/dev/null succeeds), StateSaveLocation is reachable and not full; the customer is OK with a brief scheduler pause during which no new jobs schedule and scontrol/squeue/sbatch calls return transient errors; no node recovery operation (Action:Reboot/Action:Replace) is in progress — restarting the controller mid-recovery can leave the affected node stuck.

Command:

sudo systemctl restart slurmctld && sinfo && squeue

Blast radius: brief scheduler pause; running jobs are not interrupted (slurmd keeps them going); pending queue and node states are preserved on disk via StateSaveLocation. New job submissions during the restart window receive a transient error and must be retried by the user. If systemctl restart does not return, the daemon is hung — investigate a stuck StateSaveLocation (full disk, NFS hang) before any forcible kill, since killing slurmctld with corrupt state files can lose the queue.

Slurm node name → instance ID

list-cluster-nodes does not return PrivateDnsHostname — that field is only populated by describe-cluster-node. So the mapping is a two-step call: list the instance IDs in the cluster, then describe each one to get the DNS hostname.

# 1. List candidate instance IDs (running nodes only, skip utility groups)
aws sagemaker list-cluster-nodes --cluster-name <C> --region <R> \
  --query 'ClusterNodeSummaries[?InstanceStatus.Status==`Running`].[InstanceId,InstanceGroupName,InstanceType]' \
  --output text

# 2. For each candidate, fetch the DNS hostname and match against the Slurm name
NODE="ip-10-1-2-3"   # Slurm node name
for IID in $(aws sagemaker list-cluster-nodes --cluster-name <C> --region <R> \
               --query 'ClusterNodeSummaries[?InstanceStatus.Status==`Running`].InstanceId' --output text); do
  DNS=$(aws sagemaker describe-cluster-node --cluster-name <C> --region <R> --node-id "$IID" \
          --query 'NodeDetails.PrivateDnsHostname' --output text 2>/dev/null)
  case "$DNS" in
    "$NODE."*) echo "$NODE → $IID"; break ;;
  esac
done

Scale note: the for-loop above issues one describe-cluster-node API call per Running instance until it finds a match. On clusters with thousands of running nodes that's a lot of API calls; SageMaker has a default rate limit on the Describe* family (~10 TPS) so this can take minutes and incur throttling. For large clusters, use dump_cluster_nodes_info.py (AWS samples repo awsome-distributed-training) once to generate a CSV of IP ↔ instance-ID mappings, then look up locally.


I: Resource Exhaustion

Signals: Disk full, OOM kills, "Cannot allocate memory" at os.fork(), inode exhaustion, /dev/shm full.

Diagnose (via hyperpod-ssm on the node)
df -h && df -i                             # disk + inodes
free -h                                    # RAM
df -h /dev/shm                             # shared memory
dmesg | grep -i oom | tail -10             # OOM kills
sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head -15
cat /proc/meminfo | grep Huge              # huge pages
I.1: "Cannot allocate memory" at os.fork()

Symptoms: OSError: [Errno 12] Cannot allocate memory during os.fork(), DataLoader crashes, Failed to register memory during EFA init, segfaults during NCCL.

Fix (in order):

  1. export FI_EFA_USE_HUGE_PAGE=0 — try this first; add to job script, container entrypoint, or /etc/environment. Disabling EFA huge pages avoids the fork-time memory-registration path that fails when huge pages aren't pre-allocated.

  2. Increase shared memory:

    • Docker: docker run --shm-size=8g ...

    • Kubernetes:

      volumes:
      - name: dshm
        emptyDir: { medium: Memory, sizeLimit: 8Gi }
      volumeMounts:
      - { name: dshm, mountPath: /dev/shm }
  3. Tune PyTorch DataLoader: num_workers=4 (lower), persistent_workers=True, pin_memory=False if not bottlenecked on host→GPU copy.

  4. Reduce batch size to lower parent-process memory before fork.

If you need FI_EFA_USE_HUGE_PAGE=1, pre-allocate huge pages first.

Suggested command — pre-allocate huge pages on a node (run this yourself)

Preconditions: the workload requires FI_EFA_USE_HUGE_PAGE=1 (most jobs do not — =0 is the simpler fix and resolves the fork-time error on its own); free RAM on the node can absorb the reservation (1024 × 2 MiB = 2 GiB; check with free -h first); no existing process on the node already depends on a different nr_hugepages value; customer accepts that the persistent file (/etc/sysctl.d/99-hugepages.conf) survives reboots — on a node that may later be replaced, the file is destroyed with the volumes (replacement will recreate from the AMI/lifecycle script).

Command:

cat /proc/sys/vm/nr_hugepages                             # current
echo 1024 | sudo tee /proc/sys/vm/nr_hugepages            # 1024 × 2 MiB = 2 GiB, runtime-only
echo 'vm.nr_hugepages=1024' | sudo tee -a /etc/sysctl.d/99-hugepages.conf   # persist across reboots

Blast radius: reduces RAM available to other processes on the node by ~2 GiB immediately. Persistent file change applies on every boot of this node — bake the same value into the lifecycle script so replacement nodes match. Setting FI_EFA_USE_HUGE_PAGE=1 without pre-allocation is the root cause of the fork-time failure; setting it after pre-allocation fixes that path.

I.2: Root Volume Exhausted

The default HyperPod root volume is 100 GB EBS. Do not plan to grow it post-creation — redirect heavy data to /opt/sagemaker (secondary EBS, sized at instance-group creation) or /opt/dlami/nvme (NVMe instance store on P/G families). For shared persistence use FSx for Lustre / OpenZFS or S3.

MountTypePersistenceBest for
/opt/sagemakerSecondary EBS (configurable per group)PersistentCheckpoints, app data, logs, container images
/opt/dlami/nvmeNVMe instance store (on instance types that ship with NVMe)Lost on stop/replaceScratch, caches, temp files
FSx for LustreSharedPersistentLarge datasets, shared models
FSx for OpenZFSSharedPersistentMixed workloads, snapshots
Amazon S3Object storagePersistentLarge datasets, archives
Suggested command — reclaim disk space (run this yourself)

Preconditions: root-volume exhaustion confirmed (df -h / shows near-100%); customer has identified what is consuming space (du -sh /var/* /opt/* 2>/dev/null | sort -h); no training job is currently writing to the affected paths; you have inspected /var/log/ and decided which files are safe to remove (never run a blanket wipe — target specific files identified by du); no running containers will be surprised by docker system prune.

Command:

# 1. Shrink journald — capped size, reversible by running again
sudo journalctl --vacuum-size=500M

# 2. Remove rotated logs YOU HAVE IDENTIFIED as safe to delete. Example
#    commands — review the file list first and adapt the globs:
ls -lah /var/log/*.log.* /var/log/*/*.gz 2>/dev/null   # inspect
# Then, targeted deletes for the specific logs you chose:
sudo rm -f /var/log/<specific-file>.log.N

# 3. Package-manager caches (safe):
sudo apt-get clean 2>/dev/null || sudo yum clean all 2>/dev/null

# 4. Docker prune — removes stopped containers, unused networks, dangling
#    images. Add --volumes only if you know no named volume holds training data.
docker system prune -a -f 2>/dev/null

Blast radius: journalctl --vacuum-size and package-manager clean are low-risk. Targeted rm in /var/log/ is safe for rotated-and-gzipped files (*.gz) but a blanket rm -f /var/log/*.log.* can delete logs an incident team needs — always inspect first. docker system prune -a without --volumes leaves named volumes intact; adding --volumes will delete any unattached named volumes (including ones holding model checkpoints if not mounted at prune time).

Redirect data:

# Environment variables
export TORCH_HOME=/opt/sagemaker/torch_cache
export HF_HOME=/opt/sagemaker/huggingface_cache
export TRANSFORMERS_CACHE=/opt/sagemaker/transformers_cache
export TMPDIR=/opt/dlami/nvme/tmp && mkdir -p $TMPDIR

# Training scripts
checkpoint_dir = "/opt/sagemaker/checkpoints"
cache_dir = "/opt/dlami/nvme/cache"

For K8s pods, mount /opt/sagemaker and /opt/dlami/nvme as hostPath volumes. Check the customer's lifecycle script — the awsome-distributed-training samples typically point container runtimes at these paths, but custom scripts may not. Prevention: size secondary EBS generously at instance-group creation; growing it later is more disruptive than over-provisioning up front.

I.3: OOM events

Triage signal: [P1] OOM events on node <i-xxx>.

sudo dmesg -T | grep -i -B2 -A30 "Out of memory" | tail -80
ps auxf --sort=-%mem | head -20

The fix is in the workload spec (pod resources.limits.memory, batch size, DataLoader workers) — no remediation command on the node changes state.

I.4: Inode exhaustion

Triage signal: [P1] Inode exhaustion <N>% on /. Small files (pip caches, HF caches, container image layers) can exhaust inodes before disk space.

Diagnose (read-only):

df -i /
# Top inode hoarders (by top-level directory):
sudo find / -xdev -type f 2>/dev/null | awk -F/ '{print $1"/"$2"/"$3}' | sort | uniq -c | sort -rn | head -20
Suggested command — reclaim inodes (run this yourself)

Preconditions: inode exhaustion confirmed on / (df -i / near 100%); top hoarders identified via find above; no training job is currently writing to or reading from ~/.cache/huggingface or ~/.cache/pip (these caches may hold model weights that would need to be re-downloaded — check with the customer before deleting); docker system prune --volumes is acceptable (customer has confirmed no unattached named volume holds data they need).

Command:

# 1. pip cache — fast to rebuild; safe.
rm -rf ~/.cache/pip/*

# 2. Hugging Face cache — CONTAINS DOWNLOADED MODEL WEIGHTS. Delete only
#    if the customer accepts re-download cost (can be many GB and minutes).
#    Preferably: `du -sh ~/.cache/huggingface/*` and remove only the specific
#    entries they are not using.
du -sh ~/.cache/huggingface/* 2>/dev/null   # inspect first
# Then, targeted:
rm -rf ~/.cache/huggingface/<specific-model-dir>

# 3. journald (safe):
sudo journalctl --vacuum-size=200M

# 4. Docker prune — see blast-radius note in I.2. Only add --volumes if
#    the customer has confirmed no named volume holds training data.
docker system prune -a -f 2>/dev/null || true

Blast radius: rm -rf ~/.cache/huggingface/* can destroy large model weights requiring slow re-downloads (potentially interrupting training on adjacent jobs that share the cache). docker system prune -a --volumes -f without care can delete named volumes holding checkpoints. Always inspect (du) and delete targeted paths rather than using wildcards across the whole cache. Redirect caches to /opt/sagemaker or /opt/dlami/nvme (see I.2) as a long-term fix — separate filesystems with their own inode tables.


J: Configuration

Signals: p5.48xlarge shows 96 vCPU instead of 192 (half the expected vCPU count).

Suggested command — enable SMT via ThreadsPerCore (run this yourself)

Preconditions: instance-type confirmed as one where SMT is disabled by default and the workload wants both threads (e.g., p5.48xlarge 96→192); every field for every instance group is derived from the current describe-cluster output (update-cluster replaces the whole InstanceGroups list — any mistyped field silently changes cluster config); you understand that changing ThreadsPerCore rolls the instance group through replacement.

Command:

aws sagemaker update-cluster --cluster-name <C> --region <R> \
  --instance-groups '[{"InstanceGroupName":"<G>","InstanceType":"ml.p5.48xlarge",
    "InstanceCount":<N>,"ThreadsPerCore":2,
    "LifeCycleConfig":{"SourceS3Uri":"<URI>","OnCreate":"<SCRIPT>"},
    "ExecutionRole":"<ROLE>"}]'

Blast radius: any instance group omitted from the list is deleted; any field drift (instance type, count, lifecycle config, execution role) is applied as-is. Rolls nodes through replacement — which destroys root + secondary volumes per instance. Coordinate with the workload owner before running.


K: Node Access via SSM

Direct SSH is not available on HyperPod — SSM is the primary node access method. The target format and connection procedure is identical for EKS and Slurm.

Quick-start: connect in 4 commands
CLUSTER_NAME="my-hyperpod-cluster"
REGION="us-east-1"

# 1. Cluster ID is the ARN suffix — NOT the cluster name
CLUSTER_ID=$(aws sagemaker describe-cluster \
  --cluster-name "$CLUSTER_NAME" --region "$REGION" \
  --query 'ClusterArn' --output text | cut -d/ -f2)

# 2. List nodes
aws sagemaker list-cluster-nodes --cluster-name "$CLUSTER_NAME" --region "$REGION" \
  --query 'ClusterNodeSummaries[*].[InstanceGroupName,InstanceId,InstanceStatus.Status]' --output table

# 3. Build the target
TARGET="sagemaker-cluster:${CLUSTER_ID}_<GROUP>-<INSTANCE_ID>"

# 4. Connect
aws ssm start-session --target "$TARGET" --region "$REGION"
From a Slurm node name (e.g. ip-10-1-2-3)

PrivateDnsHostname is only returned by describe-cluster-node (not by list-cluster-nodes), so map via the two-step procedure in § H "Slurm node name → instance ID" — then build the SSM target with the resolved instance ID.

Non-interactive command execution
bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target "$TARGET" --region "$REGION" \
  'nvidia-smi && free -h && df -h'
Essential on-node checks
CheckCommand
System healthuptime && free -h && df -h
GPU (NVIDIA)nvidia-smi
Accelerator (Trainium)neuron-ls && neuron-top -n 1
EFAfi_info -p efa
NCCL/EFA envenv | grep -E "FI_|NCCL_"
OOM / errorsdmesg | grep -i "oom|xid|nvrm|neuron" | tail -20
Provisioningcat /var/log/provision/provisioning.log
Slurmd (Slurm only)sudo systemctl status slurmd
Prerequisites
session-manager-plugin --version
# If missing, install session-manager-plugin for your OS — see the
# AWS Systems Manager Session Manager documentation for current packages.

IAM:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "sagemaker:DescribeCluster",
      "sagemaker:DescribeClusterNode",
      "sagemaker:ListClusterNodes",
      "ssm:StartSession",
      "ssm:TerminateSession"
    ],
    "Resource": "*"
  }]
}
SSM not working?
ErrorFix
SessionManagerPlugin is not foundInstall plugin; restart terminal
Target is not connectedUse sagemaker-cluster: prefix (not bare i-xxx); verify region; verify node Running
InvalidTarget / ValidationExceptionFormat must be exactly sagemaker-cluster:<CLUSTER_ID>_<GROUP>-<INSTANCE_ID>
Access deniedNeed ssm:StartSession, sagemaker:DescribeCluster, sagemaker:ListClusterNodes
Connection timeoutCheck VPC endpoints (SSM, SSMMessages, EC2Messages); verify node Running

L: Log Collection

Delegate to hyperpod-issue-report for comprehensive S3-stored diagnostics.

LogGroupStream
Lifecycle scripts/aws/sagemaker/Clusters/<name>/<id>LifecycleConfig/<group>/<instance-id>
Health monitoring/aws/sagemaker/Clusters/<name>/<id>SagemakerHealthMonitoringAgent/<group>/<instance-id>

M: Container Runtime

Signals: CrashLoopBackOff, ImagePullBackOff, RunContainerError, container OOM kills (EKS clusters).

# Pod-level (from workstation)
kubectl describe pod <POD> -n <NAMESPACE>
kubectl logs <POD> -n <NAMESPACE> --previous       # logs from last crash

# On-node (via SSM)
bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target <TARGET> --region <REGION> \
  'sudo crictl ps -a | head -20 && sudo crictl logs --tail 30 <CONTAINER_ID> && journalctl -u containerd --no-pager -n 50'
SymptomCauseFix
CrashLoopBackOffTraining process crashes repeatedlykubectl logs --previous; likely OOM, missing lib, or NCCL error
OOMKilledContainer exceeded memory limitRaise resources.limits.memory or reduce batch size
ImagePullBackOffImage not found or auth failureVerify ECR URI; ECR access via VPC endpoint or internet
RunContainerErrorRuntime can't start containerjournalctl -u containerd; may be disk full or GPU device issue
ContainerCreating stuckVolume mount or device plugin issueCheck EFA device plugin DaemonSet, volume mounts, CSI drivers

If containerd is crashing or OOM-ing, check disk on /var/lib/containerd (lives on the root 100 GB volume). Move container storage to /opt/sagemaker if needed.


N: Kernel & System

Signals: Kernel panic, watchdog timeout, NMI, system hang, unexpected reboot not explained by HyperPod health monitoring.

bash skills/hyperpod-ssm/scripts/ssm-exec.sh --target <TARGET> --region <REGION> \
  'dmesg | grep -iE "panic|watchdog|hung_task|NMI|nvrm|Call Trace|BUG:" | tail -30 && journalctl -b -1 --no-pager -n 50 2>/dev/null || echo "No previous boot journal"'
SignalLikely causeAction
Kernel panic - not syncingCritical kernel errorFull dmesg; nvrm-related signatures suggest NVIDIA driver — reboot, replace if recurring
watchdog: BUG: soft lockupCPU stuck in kernel codeOften NVLink/PCIe issues on GPU instances; reboot, replace if recurring
hung_task_timeoutProcess stuck in uninterruptible sleepCheck disk I/O (iostat), NFS hangs, deadlocked GPU ops
NMI receivedHardware interruptDrain and replace (§ F)
mce: [Hardware Error]Machine check exceptionCPU/memory hardware failure — replace
Repeated unexpected rebootsHealth agent triggered reboot for HW faultCheck SagemakerHealthMonitoringAgent logs; expected if auto-repair is working

Previous boot logs:

journalctl -b -1 --no-pager | tail -100
last reboot | head -5
who -b

Recurring panics on the same node after reboot → hardware is likely bad; drain and replace (§ F).


O: CNI / Pod Networking

VPC CNI plugin (aws-node) failures prevent pods from getting IP addresses — breaks all pod networking on affected nodes. Pattern seen in customer cases: HyperPod GPU node is Ready but aws-node is in CrashLoopBackOff, pod sandbox creation fails with gRPC 127.0.0.1:50051 refused.

Diagnose
kubectl get ds -n kube-system aws-node                     # DESIRED vs READY mismatch
kubectl get pods -n kube-system -l k8s-app=aws-node -o wide  # CrashLoopBackOff / Error / high RESTARTS

# Pod logs
kubectl logs -n kube-system <aws-node-pod> -c aws-node --tail=100
kubectl logs -n kube-system <aws-node-pod> -c aws-eks-nodeagent --tail=50

# IPAMD-specific
kubectl logs -n kube-system <aws-node-pod> -c aws-node --tail=100 | grep -iE "ipamd|eni|ip pool|failed"

# Related DaemonSets
kubectl get pods -n kube-system -l k8s-app=kube-proxy
kubectl get pods -n kube-system -l k8s-app=kube-dns
Log patternRoot causeFix
gRPC connection refused 127.0.0.1:50051IPAMD not running; aws-node init container failedRestart aws-node pod; check node IAM role
Failed to create ENI / ENI limit reachedInstance-type ENI limit reachedReduce pod density or enable prefix delegation
UnauthorizedOperation: ec2:CreateNetworkInterfaceNode IAM role missing EC2 permissionsAdd AmazonEKS_CNI_Policy to the node role
Failed to pull image on aws-nodeECR unreachable in private VPCAdd com.amazonaws.<region>.ecr.api and .dkr VPC endpoints
Insufficient IP addressesSubnet exhaustedLarger subnet or enable prefix delegation
ipamd: failed to increase IP poolCannot allocate warm-pool IPsCheck ENI limits, subnet capacity, SG rules

Diagnose (read-only):

aws ec2 describe-subnets --subnet-ids <SUBNET_ID> --region <REGION> \
  --query 'Subnets[0].{SubnetId:SubnetId,AvailableIPs:AvailableIpAddressCount,CIDR:CidrBlock}'
Suggested command — restart a crashing aws-node pod (run this yourself)

Preconditions: root cause has been investigated and is plausibly transient (e.g., a stuck IPAMD process). For persistent crashes from IAM, VPC, or subnet exhaustion, fix the underlying issue first — restarting the pod will only loop. The customer accepts brief CNI unavailability on this node (a few seconds while the daemonset respawns).

Command:

kubectl delete pod -n kube-system <aws-node-pod-name>

Blast radius: the daemonset respawns the pod within seconds; during the gap, pods being scheduled or deleted on this node may briefly fail IP assignment. Already-running pods with assigned IPs are unaffected. Reversible by definition (replacement pod is identical).

Suggested command — enable prefix delegation for higher pod density (run this yourself)

Preconditions: cluster admin has approved the operational change; you understand that prefix delegation changes ENI allocation behavior for every node managed by this daemonset; no existing workload relies on the previous per-IP allocation pattern.

Command:

kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true

Blast radius: cluster-wide change to the VPC CNI configuration. New pods scheduled after the rollout get IPs from ENI prefixes rather than individual secondary IPs. Existing pods keep their IPs. Reverting requires kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION- (note the trailing -) and may leave ENIs in an unexpected state until nodes cycle.

The node role needs AmazonEKS_CNI_Policy or equivalent: ec2:CreateNetworkInterface, DeleteNetworkInterface, DescribeNetworkInterfaces, AssignPrivateIpAddresses, UnassignPrivateIpAddresses, AttachNetworkInterface, DetachNetworkInterface.

Escalate

If aws-node keeps crashing after restart with no clear error, and IAM + VPC + subnet are all correct, escalate with:

kubectl describe ds -n kube-system aws-node
kubectl logs -n kube-system -l k8s-app=aws-node --tail=200
kubectl get nodes -o wide

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs a command-line tool, Needs Python, Needs Node.js

Security

What our scanner noticed· Low risk

  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS Labs
Publisher
AWS Labs (Official)
Source
awslabs/agent-plugins · plugins/sagemaker-ai/skills/hyperpod-node-debugger · commit fbefb37
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS Labs.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download hyperpod-node-debugger.zip