{"record":{"id":"e7fd80c311df4847","repo":"kubernetes/kops","slug":"instance-s-from-akamai-linode-metadata-was-empt","errorCode":null,"errorMessage":"instance %s from Akamai (Linode) metadata was empty","messagePattern":"instance (.+?) from Akamai \\(Linode\\) metadata was empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/linode/linodemetadata/authenticator.go","lineNumber":125,"sourceCode":"\n\tinstanceResp, err := client.Do(instanceReq)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"fetching instance metadata: %w\", err)\n\t}\n\tdefer instanceResp.Body.Close()\n\n\tif instanceResp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"fetching instance metadata: unexpected status code %d\", instanceResp.StatusCode)\n\t}\n\n\tinstanceBytes, err := io.ReadAll(instanceResp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"reading instance metadata response: %w\", err)\n\t}\n\n\tvalue := parseLinodeMetadataValue(string(instanceBytes), key)\n\tif value == \"\" {\n\t\treturn \"\", fmt.Errorf(\"instance %s from Akamai (Linode) metadata was empty\", key)\n\t}\n\treturn value, nil\n}\n\n// parseLinodeMetadataValue parses the Akamai (Linode) metadata response for the given key\n// and returns the value as a string.\nfunc parseLinodeMetadataValue(metadata string, key string) string {\n\tprefix := key + \":\"\n\tfor _, line := range strings.Split(metadata, \"\\n\") {\n\t\tline = strings.TrimSpace(line)\n\t\tif !strings.HasPrefix(line, prefix) {\n\t\t\tcontinue\n\t\t}\n\t\treturn strings.TrimSpace(strings.TrimPrefix(line, prefix))\n\t}\n\treturn \"\"\n}\n","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/linode/linodemetadata/authenticator.go#L107-L143","documentation":"After successfully reading the metadata response body, getLinodeMetadataValue parses it with parseLinodeMetadataValue for the requested key. If the key is absent or its value is blank in the metadata document, the empty string is treated as an error. This means the metadata endpoint answered, but did not contain the requested field.","triggerScenarios":"parseLinodeMetadataValue(string(instanceBytes), key) returns \"\" because the metadata JSON/document has no entry for key, or the entry exists but is an empty string. Callers: GetMetadataValue and CreateToken requesting a key (e.g. region, instance id, token) that the endpoint did not return.","commonSituations":"Requesting a metadata key not present on this instance type or provider generation; typo'd key name; metadata service enabled but returns a partial/empty document during instance provisioning; unit test TestGetLinodeMetadataValueMissingKey deliberately hits this with a missing key.","solutions":["Verify the key name matches exactly what the Linode metadata service exposes","Query the metadata endpoint manually (curl the URL) and inspect the raw document for the key","Confirm the metadata service is fully initialized on the instance (retry shortly after boot)","Handle the empty value at the call site with a sensible default or clearer error naming the expected key"],"exampleFix":"// before\nvalue := parseLinodeMetadataValue(string(instanceBytes), key)\nif value == \"\" {\n\treturn \"\", fmt.Errorf(\"instance %s from Akamai (Linode) metadata was empty\", key)\n}\n// after\nvalue := parseLinodeMetadataValue(string(instanceBytes), key)\nif value == \"\" {\n\treturn \"\", fmt.Errorf(\"instance %s from Akamai (Linode) metadata was empty: check that key %q is exposed by the metadata service\", key, key)\n}","handlingStrategy":"validation","validationCode":"value := parseLinodeMetadataValue(string(instanceBytes), key)\nif value == \"\" { return fmt.Errorf(\"metadata key %q missing; available keys: %s\", key, doc) }","typeGuard":null,"tryCatchPattern":"v, err := getLinodeMetadataValue(ctx, key)\nif err != nil {\n\tif strings.Contains(err.Error(), \"was empty\") { v = defaultValueFor(key) }\n\treturn err\n}","preventionTips":["Check the raw metadata document (curl the endpoint) when a key comes back empty","Confirm the Linode metadata service is enabled and fully initialized at boot","Use exact, provider-documented key names","Provide defaults for optional keys at the call site"],"tags":["linode","metadata","empty-value"],"backgroundTag":"missing-metadata-key","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"}