{"record":{"id":"5561ea47c7c5ce2c","repo":"kubernetes/kops","slug":"querying-attested-document-w","errorCode":null,"errorMessage":"querying attested document: %w","messagePattern":"querying attested document: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"upup/pkg/fi/cloudup/azure/azuremetadata/authenticator.go","lineNumber":64,"sourceCode":"\t// bootstrap.Authenticator.CreateToken carries no context; the IMDS HTTP client's own timeout\n\t// bounds these calls.\n\tctx := context.TODO()\n\n\t// Query IMDS for the VM's resource ID.\n\tmetadata, err := QueryComputeInstanceMetadata(ctx)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"querying instance metadata: %w\", err)\n\t}\n\tif metadata.ResourceID == \"\" {\n\t\treturn \"\", fmt.Errorf(\"missing resource ID\")\n\t}\n\tklog.V(4).Infof(\"Azure authenticator obtained resource ID %q\", metadata.ResourceID)\n\n\t// Query IMDS for a PKCS7-signed attested document containing the nonce.\n\tnonce := NonceForBody(body)\n\tdoc, err := queryIMDSAttestedDocument(ctx, nonce)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"querying attested document: %w\", err)\n\t}\n\tif doc.Signature == \"\" {\n\t\treturn \"\", fmt.Errorf(\"empty attested document signature\")\n\t}\n\tklog.V(2).Infof(\"Azure authenticator obtained attested document for %q\", metadata.ResourceID)\n\n\t// Token format: \"x-azure-id <resourceID> <base64-pkcs7-signature>\"\n\treturn AzureAuthenticationTokenPrefix + metadata.ResourceID + \" \" + doc.Signature, nil\n}\n","sourceCodeStart":46,"sourceCodeEnd":74,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/azuremetadata/authenticator.go#L46-L74","documentation":"CreateToken wraps failures from queryIMDSAttestedDocument — the GET of /metadata/attested/document (PKCS7-signed document containing a nonce) — with the \"querying attested document\" prefix. The attested document proves to the control plane that this token was minted on the actual Azure VM, so failure aborts bootstrap token creation.","triggerScenarios":"CreateToken called with a request body; NonceForBody derives a nonce; the inner queryIMDS call fails on request creation, transport error (timeout/refused), non-200 status (e.g. 400/404/429 for attested endpoint), read error, or unmarshal error.","commonSituations":"IMDS throttling (429) during mass node rollouts; VM image without attested-data support or very old IMDS; API version compatibility issues with the attested endpoint; transient IMDS outage; NSG blocking IMDS.","solutions":["Test the attested endpoint directly: curl -H Metadata:true 'http://169.254.169.254/metadata/attested/document?api-version=2025-04-07&nonce=<hex>' and read the wrapped error/status","Retry with backoff on 429/5xx — IMDS throttles aggressively","Verify VM/OS image supports attested data and the api-version is current","Check for network interference with the link-local IMDS address"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Verify attested document endpoint responds before bootstrap\nfunc attestedOK(nonce string) error {\n    c := &http.Client{Timeout: 5 * time.Second, Transport: &http.Transport{Proxy: nil}}\n    u := \"http://169.254.169.254/metadata/attested/document?api-version=2025-04-07&nonce=\" + url.QueryEscape(nonce)\n    req, _ := http.NewRequest(\"GET\", u, nil)\n    req.Header.Set(\"Metadata\", \"true\")\n    resp, err := c.Do(req)\n    if err != nil { return err }\n    defer resp.Body.Close()\n    if resp.StatusCode != 200 { return fmt.Errorf(\"attested endpoint status %d\", resp.StatusCode) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Back off specifically on 429/503 from the attested endpoint\nfor attempt := 0; attempt < 5; attempt++ {\n    token, err := authenticator.CreateToken(body)\n    if err == nil { use(token); break }\n    if strings.Contains(err.Error(), \"status 429\") || strings.Contains(err.Error(), \"status 503\") {\n        time.Sleep(time.Duration(1<<attempt) * time.Second)\n        continue\n    }\n    return err\n}","preventionTips":["Avoid stampedes: stagger node boots to reduce IMDS throttling","Confirm VM images/generations support attested data before rollout","Test the attested endpoint with curl during image bring-up","Keep the IMDS api-version current"],"tags":["azure","imds","attestation","bootstrap"],"backgroundTag":"imds-attested-document-failed","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"}