kubernetes/kops · error
failed to load AWS config: %w
Error message
failed to load AWS config: %w
What it means
GetMetadataLocalIP resolves the node's internal IP from cloud metadata. On AWS it first loads an AWS SDK v2 default config; if that fails (no region, bad credentials/IMDS availability config) it wraps the SDK error. Without a usable config the EC2 IMDS client cannot be built, so the function returns early.
Source
Thrown at nodeup/pkg/model/context.go:595
// RunningOnGCE returns true if we are running on GCE
func (c *NodeupModelContext) RunningOnGCE() bool {
return c.CloudProvider() == kops.CloudProviderGCE
}
// RunningOnAzure returns true if we are running on Azure
func (c *NodeupModelContext) RunningOnAzure() bool {
return c.CloudProvider() == kops.CloudProviderAzure
}
// GetMetadataLocalIP returns the local IP address read from metadata
func (c *NodeupModelContext) GetMetadataLocalIP(ctx context.Context) (string, error) {
var internalIP string
switch c.BootConfig.CloudProvider {
case kops.CloudProviderAWS:
config, err := awsconfig.LoadDefaultConfig(ctx)
if err != nil {
return "", fmt.Errorf("failed to load AWS config: %w", err)
}
metadata := imds.NewFromConfig(config)
localIPv4, err := getMetadata(ctx, metadata, "local-ipv4")
if err != nil {
return "", fmt.Errorf("failed to get local-ipv4 address from ec2 metadata: %w", err)
}
internalIP = localIPv4
case kops.CloudProviderHetzner:
client := hcloudmetadata.NewClient()
privateNetworksYaml, err := client.PrivateNetworks()
if err != nil {
return "", fmt.Errorf("failed to get private networks from hetzner cloud metadata: %w", err)
}
var privateNetworks []struct {
IP net.IP `json:"ip"`
AliasIPs []net.IP `json:"alias_ips"`
InterfaceNum int `json:"interface_num"`View on GitHub (pinned to 4c8573c808)
Solutions
- Fix instance metadata access: ensure metadata options are enabled and IMDSv2 hop limit ≥ 2 (`aws ec2 modify-instance-metadata-options --http-tokens required --http-put-response-hop-limit 2`)
- Check network/firewall rules allow 169.254.169.254 from the node
- Verify BootConfig.CloudProvider is correct — this path only runs for AWS; a misconfigured provider should be corrected in the cluster spec and `kops update cluster` re-run
- Set AWS_REGION / AWS_DEFAULT_REGION env on the node config if IMDS is intentionally unavailable
Defensive patterns
Strategy: try-catch
Validate before calling
// check IMDS reachability before nodeup runs if !curl -s --max-time 2 http://169.254.169.254/latest/api/token >/dev/null; then echo "EC2 IMDS unreachable; fix metadata options before nodeup" fi
Try / catch
ip, err := c.GetMetadataLocalIP(ctx)
if err != nil {
if strings.Contains(err.Error(), "failed to load AWS config") {
klog.Errorf("AWS SDK config unavailable — check IMDS enabled, hop limit >= 2, and AWS_REGION: %v", err)
}
return err
} Prevention
- Keep EC2 metadata options enabled with IMDSv2 hop limit >= 2
- Allow 169.254.169.254 egress on the node
- Set CloudProvider correctly in the cluster spec
- Only run this code path on actual AWS nodes
When it happens
Trigger: awsconfig.LoadDefaultConfig fails inside GetMetadataLocalIP on an AWS node — typically no region resolvable (no IMDS, no env/AWS_REGION) because IMDS is unreachable or disabled (IMDSv2 hop limit, metadata options set to disabled).
Common situations: EC2 instance metadata disabled or blocked by iptables/network policy; running nodeup outside AWS (e.g. in CI) with BootConfig.CloudProvider misconfigured as AWS; IMDSv2 hop limit too low for container/pod-based execution.
Related errors
- failed to get local-ipv4 address from ec2 metadata: %w
- error reading instance-id from AWS metadata: %v
- failed to get machine type: %w
- failed to get instance metadata type: %w
- error reading local-ipv4 from AWS metadata: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e86366d41e2a229a.
Report an issue: GitHub.