{"record":{"id":"4169d2e50393f329","repo":"kubernetes/kops","slug":"unhandled-aws-metadata-path-q","errorCode":null,"errorMessage":"unhandled aws metadata path %q","messagePattern":"unhandled aws metadata path %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/context.go","lineNumber":245,"sourceCode":"\tconfig, err := awsconfig.LoadDefaultConfig(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to load AWS config: %w\", err)\n\t}\n\n\tclient := imds.NewFromConfig(config)\n\n\tif strings.HasPrefix(path, \"/meta-data/\") {\n\t\ts, err := client.GetMetadata(ctx, &imds.GetMetadataInput{\n\t\t\tPath: strings.TrimPrefix(path, \"/meta-data/\"),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error reading from AWS metadata service: %v\", err)\n\t\t}\n\t\tdefer s.Content.Close()\n\t\treturn io.ReadAll(s.Content)\n\t}\n\t// There are others (e.g. user-data), but as we don't use them yet let's not expose them\n\treturn nil, fmt.Errorf(\"unhandled aws metadata path %q\", path)\n}\n\n// readHTTPLocation reads an http (or https) url.\n// It returns the contents, or an error on any non-200 response.  On a 404, it will return os.ErrNotExist\n// It will retry a few times on a 500 class error\nfunc (c *VFSContext) readHTTPLocation(httpURL string, httpHeaders map[string]string, opts vfsOptions) ([]byte, error) {\n\tvar body []byte\n\n\tdone, err := RetryWithBackoff(opts.backoff, func() (bool, error) {\n\t\tklog.V(4).Infof(\"Performing HTTP request: GET %s\", httpURL)\n\t\treq, err := http.NewRequest(\"GET\", httpURL, nil)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tfor k, v := range httpHeaders {\n\t\t\treq.Header.Add(k, v)\n\t\t}\n\t\tresponse, err := http.DefaultClient.Do(req)","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/context.go#L227-L263","documentation":"readAWSMetadata only supports paths under /meta-data/; user-data and other IMDS trees are intentionally not exposed. Any metadata://aws URL whose path does not start with /meta-data/ returns this error.","triggerScenarios":"ReadFile('metadata://aws/user-data') or ReadFile('metadata://aws/dynamic/instance-identity/document') - any aws metadata path not prefixed with /meta-data/.","commonSituations":"Trying to fetch EC2 user-data through the vfs metadata scheme; copying GCE-style metadata paths (computeMetadata/v1 style) into the aws scheme.","solutions":["Use a /meta-data/... path, e.g. metadata://aws/meta-data/instance-id","For user-data, fetch http://169.254.169.254/latest/user-data directly with an HTTP client","For instance identity documents, use the AWS SDK (ec2rolecreds / imds client) rather than this path"],"exampleFix":"// before\nvfs.Context.ReadFile(\"metadata://aws/user-data\")\n// after\nvfs.Context.ReadFile(\"metadata://aws/meta-data/instance-id\")","handlingStrategy":"validation","validationCode":"func validateAWSMetadataPath(loc string) error {\n\tu, err := url.Parse(loc)\n\tif err != nil || u.Scheme != \"metadata\" || u.Host != \"aws\" {\n\t\treturn nil\n\t}\n\tif !strings.HasPrefix(u.Path, \"/meta-data/\") {\n\t\treturn fmt.Errorf(\"only /meta-data/* paths are supported: %q\", loc)\n\t}\n\treturn nil\n}","typeGuard":"func isSupportedAWSMetadataPath(loc string) bool {\n\tu, err := url.Parse(loc)\n\treturn err == nil && u.Scheme == \"metadata\" && u.Host == \"aws\" && strings.HasPrefix(u.Path, \"/meta-data/\")\n}","tryCatchPattern":"data, err := vfs.Context.ReadFile(loc)\nif err != nil && strings.Contains(err.Error(), \"unhandled aws metadata path\") {\n\treturn fmt.Errorf(\"use /meta-data/... or fetch user-data via IMDS HTTP directly: %w\", err)\n}","preventionTips":["Restrict metadata://aws reads to a small allowlist of /meta-data/ keys","Fetch user-data and identity documents directly from IMDS or the AWS SDK instead","Document the /meta-data/ prefix requirement where the location string is templated"],"tags":["aws","imds","unsupported-path"],"backgroundTag":"unsupported-path","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"}