kubernetes/kops · error
empty attested document signature
Error message
empty attested document signature
What it means
The attested document endpoint returned HTTP 200 and valid JSON, but the signature field was empty. The authenticator requires a non-empty PKCS7 signature to construct the "x-azure-id <resourceID> <signature>" bootstrap token, so it rejects the response as unusable.
Source
Thrown at upup/pkg/fi/cloudup/azure/azuremetadata/authenticator.go:67
// Query IMDS for the VM's resource ID.
metadata, err := QueryComputeInstanceMetadata(ctx)
if err != nil {
return "", fmt.Errorf("querying instance metadata: %w", err)
}
if metadata.ResourceID == "" {
return "", fmt.Errorf("missing resource ID")
}
klog.V(4).Infof("Azure authenticator obtained resource ID %q", metadata.ResourceID)
// Query IMDS for a PKCS7-signed attested document containing the nonce.
nonce := NonceForBody(body)
doc, err := queryIMDSAttestedDocument(ctx, nonce)
if err != nil {
return "", fmt.Errorf("querying attested document: %w", err)
}
if doc.Signature == "" {
return "", fmt.Errorf("empty attested document signature")
}
klog.V(2).Infof("Azure authenticator obtained attested document for %q", metadata.ResourceID)
// Token format: "x-azure-id <resourceID> <base64-pkcs7-signature>"
return AzureAuthenticationTokenPrefix + metadata.ResourceID + " " + doc.Signature, nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect the raw IMDS attested response with curl to see whether a signature field is returned normally
- Verify api-version currency and re-test; pin/upgrade to a supported version
- Rule out spoofing: check routes/iptables for anything answering on 169.254.169.254
- If the VM is degraded (run 'az vm rerun' / redeploy) to restore the IMDS signing service
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: fetch the attested document and assert a non-empty signature
resp, err := http.Get("http://169.254.169.254/metadata/attested/document?api-version=2025-04-07&nonce=test")
// (set Metadata:true header in production code)
var doc struct{ Signature string `json:"signature"` }
json.NewDecoder(resp.Body).Decode(&doc)
if doc.Signature == "" { return errors.New("IMDS returned empty attestation signature") } Type guard
func hasValidSignature(d *struct{ Signature string }) bool {
return d != nil && strings.TrimSpace(d.Signature) != ""
} Try / catch
// Treat empty-signature as unrecoverable config/env issue: fail fast with diagnostics
if err != nil {
return fmt.Errorf("bootstrap aborted (attestation): %w", err)
} Prevention
- Verify a signature comes back from the attested endpoint on every new image/region
- Audit routes and iptables for anything impersonating 169.254.169.254
- Redeploy VMs whose IMDS behaves abnormally instead of retrying indefinitely
When it happens
Trigger: queryIMDSAttestedDocument returns an attestedDocument struct whose signature field is an empty string — the JSON lacked the "signature" key or it was empty/null.
Common situations: Intercepting software returning 200 with crafted JSON; Azure IMDS behavior/shape change for the api-version in use; VM in a degraded state where signing service returns empty payloads; accidental hit of a spoofed 169.254.169.254 responder.
Related errors
- querying attested document: %w
- empty subscription ID
- decoding PKCS7 signature: %w
- parsing PKCS7 signature: %w
- verifying PKCS7 signature: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/c6d6df7d1180eaed.
Report an issue: GitHub.