{"record":{"id":"ffce995348b85572","repo":"kubernetes/kops","slug":"getting-primary-mac-address-from-ec2-metadata-w","errorCode":null,"errorMessage":"getting primary MAC address from ec2 metadata: %w","messagePattern":"getting primary MAC address from ec2 metadata: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodeup/pkg/model/networking/eni_networking.go","lineNumber":196,"sourceCode":"\t\tType:            nodetasks.FileType_File,\n\t\tAfterPackages:   true,\n\t\tOnChangeExecute: [][]string{{\"systemctl\", \"restart\", \"systemd-networkd\"}},\n\t})\n\treturn nil\n}\n\n// primaryInterfaceName gives the name of the primary network interface. It gets the MAC address\n// of the primary ENI (device-number 0) from the IMDS item \"mac\". Then it compares this MAC\n// address with the physical network interfaces in sysfs.\nfunc primaryInterfaceName(ctx context.Context) (string, error) {\n\tconfig, err := awsconfig.LoadDefaultConfig(ctx)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"loading AWS config: %w\", err)\n\t}\n\tmetadata := imds.NewFromConfig(config)\n\tresp, err := metadata.GetMetadata(ctx, &imds.GetMetadataInput{Path: \"mac\"})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"getting primary MAC address from ec2 metadata: %w\", err)\n\t}\n\tdefer resp.Content.Close()\n\tmac, err := io.ReadAll(resp.Content)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"reading primary MAC address from ec2 metadata: %w\", err)\n\t}\n\n\treturn findPhysicalInterfaceByMAC(\"/sys/class/net\", strings.TrimSpace(string(mac)))\n}\n\n// findPhysicalInterfaceByMAC gives the name of the physical network interface that has the\n// specified MAC address. The function ignores the virtual interfaces (veths, bridges, VLANs),\n// because a virtual interface can have the same MAC address as a physical interface. The\n// function gives an error if it does not find exactly one physical interface with this MAC\n// address.\nfunc findPhysicalInterfaceByMAC(sysClassNet string, mac string) (string, error) {\n\tentries, err := os.ReadDir(sysClassNet)\n\tif err != nil {","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/nodeup/pkg/model/networking/eni_networking.go#L178-L214","documentation":"Thrown when the IMDS GetMetadata call for the 'mac' item fails. nodeup queries EC2 instance metadata for the primary ENI's MAC address (device-index 0); any IMDS failure — unreachable endpoint, throttling, IMDSv2 token issues, hop-limit, or the key missing — surfaces here.","triggerScenarios":"imds.NewFromConfig(config).GetMetadata(ctx, &imds.GetMetadataInput{Path: \"mac\"}) returns an error: metadata endpoint unreachable (169.254.169.254), IMDS disabled via instance metadata options (http-tokens required but token fetch fails, or metadata disabled), hop limit too low inside containers, or transient 5xx/throttle.","commonSituations":"Instance launched with MetadataOptions HttpTokens=required but IMDSv2 token acquisition broken; IMDS put-response hop-limit 1 while nodeup runs in a container (need 2); firewall/iptables blocking link-local 169.254.169.254; bare-metal/non-EC2 environment without IMDS.","solutions":["Verify IMDS reachability: curl -H 'X-aws-ec2-metadata-token: <token>' -v http://169.254.169.254/latest/meta-data/mac","Check EC2 instance metadata options: IMDS must be enabled (not 'Disabled') and hop limit >= 2 if running nodeup in a container","Confirm no host firewall/NAT rules block traffic to 169.254.169.254","Retry after transient failure — re-run nodeup; IMDS throttling/5xx is typically temporary"],"exampleFix":"// before: IMDS disabled\naws ec2 modify-instance-metadata-options --instance-id i-... --http-endpoint disabled\n// after\naws ec2 modify-instance-metadata-options --instance-id i-... --http-endpoint enabled --http-put-response-hop-limit 2","handlingStrategy":"retry","validationCode":"token := curl PUT http://169.254.169.254/latest/api/token  # verify IMDS reachable before nodeup\n// in Go: probe imds.GetMetadata(ctx, &imds.GetMetadataInput{Path: \"instance-id\"}) first","typeGuard":null,"tryCatchPattern":"var resp *imds.GetMetadataOutput\nerr := retry.Do(func() error {\n    r, err := metadata.GetMetadata(ctx, &imds.GetMetadataInput{Path: \"mac\"})\n    resp = r\n    return err\n}, retry.Attempts(3), retry.Delay(time.Second))","preventionTips":["Set IMDS hop limit to 2 when nodeup runs in containers","Never launch instances with metadata http-endpoint disabled","Keep IMDS tokens enabled (IMDSv2) and test token fetch in AMI validation","Avoid iptables rules that block 169.254.169.254"],"tags":["aws","imds","ec2","network"],"backgroundTag":"imds-unreachable","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}