{"record":{"id":"3fd131911f144920","repo":"kubernetes/kops","slug":"unmarshalling-imds-response-w","errorCode":null,"errorMessage":"unmarshalling IMDS response: %w","messagePattern":"unmarshalling IMDS response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/azure/azuremetadata/imds.go","lineNumber":95,"sourceCode":"\n\tresp, err := imdsHTTPClient.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"querying IMDS %s: %w\", path, err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"querying IMDS %s: status %d\", path, resp.StatusCode)\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"reading IMDS response: %w\", err)\n\t}\n\tklog.V(4).Infof(\"Azure IMDS response: %d bytes\", len(body))\n\n\tif err := json.Unmarshal(body, result); err != nil {\n\t\treturn fmt.Errorf(\"unmarshalling IMDS response: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// QueryComputeInstanceMetadata queries Azure IMDS for compute instance metadata.\n// https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service#instance-metadata\nfunc QueryComputeInstanceMetadata(ctx context.Context) (*InstanceMetadata, error) {\n\tmetadata := &InstanceMetadata{}\n\tparams := url.Values{\"format\": {\"json\"}}\n\tif err := queryIMDS(ctx, \"/metadata/instance/compute\", params, metadata); err != nil {\n\t\treturn nil, err\n\t}\n\treturn metadata, nil\n}\n\n// queryIMDSAttestedDocument queries the Azure IMDS attested document endpoint. The nonce is\n// included in the PKCS7 signed content for replay protection.","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/azuremetadata/imds.go#L77-L113","documentation":"queryIMDS read the IMDS response but json.Unmarshal failed to decode it into the target struct (InstanceMetadata or attestedDocument), wrapped as \"unmarshalling IMDS response\". The library throws this because it strictly expects the documented IMDS JSON schema; any deviation means the data cannot be trusted for identity.","triggerScenarios":"The body returned from IMDS is not the expected JSON: HTML error pages, empty body, a proxy/captive-portal response, or an IMDS schema change for the pinned api-version 2025-04-07.","commonSituations":"A device answering on 169.254.169.254 with non-JSON content (VPN software, dnsmasq, custom route); Azure changing response shape; empty 200 responses from a degraded IMDS.","solutions":["Dump the raw response with curl to see what's actually returned at 169.254.169.254","Eliminate interceptors: check routes/iptables/dns for hijacked link-local traffic","Confirm api-version compatibility; upgrade kOps if the IMDS schema changed","Redeploy/rerun the VM if IMDS is degraded"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the expected IMDS JSON shape before trusting it\nvar probe struct {\n    SubscriptionID string `json:\"subscriptionId\"`\n    ResourceID     string `json:\"resourceId\"`\n}\nbody, _ := io.ReadAll(resp.Body)\nif err := json.Unmarshal(body, &probe); err != nil {\n    return fmt.Errorf(\"IMDS returned non-JSON payload (%d bytes): %q\", len(body), truncate(body))\n}","typeGuard":null,"tryCatchPattern":"// Fail fast and dump a redacted snippet of the offending payload for diagnosis\nif err != nil {\n    return fmt.Errorf(\"imds schema mismatch, aborting bootstrap: %w\", err)\n}","preventionTips":["Check for and remove any software answering on 169.254.169.254 (VPN/dns/route hijacks)","Compare raw IMDS output against the documented schema after each api-version bump","Validate IMDS JSON as an image bring-up smoke test"],"tags":["azure","imds","json","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}