kubernetes/kops · error
failed to read metadata information %s: %v
Error message
failed to read metadata information %s: %v
What it means
After a successful 200 response from the droplet metadata service, getMetadata reads the response body with io.ReadAll. This error is returned if streaming the body fails (connection reset mid-read, timeout, truncated response).
Source
Thrown at pkg/nodeidentity/do/identify.go:112
oauthClient := oauth2.NewClient(context.TODO(), tokenSource)
return godo.NewClient(oauthClient), nil
}
func getMetadata(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("failed to get metadata URL %s: %v", url, err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("droplet metadata returned non-200 status code: %d", resp.StatusCode)
}
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("failed to read metadata information %s: %v", url, err)
}
return string(bodyBytes), nil
}
// IdentifyNode queries DigitalOcean for the node identity information.
func (i *nodeIdentifier) IdentifyNode(ctx context.Context, node *corev1.Node) (*nodeidentity.Info, error) {
providerID := node.Spec.ProviderID
if providerID == "" {
return nil, errors.New("provider ID cannot be empty")
}
const prefix = "digitalocean://"
if !strings.HasPrefix(providerID, prefix) {
return nil, fmt.Errorf("provider ID %q is missing prefix %q", providerID, prefix)
}
instanceID := strings.TrimPrefix(providerID, prefix)View on GitHub (pinned to 4c8573c808)
Solutions
- Retry the metadata request; this is usually transient
- Check droplet network health (link-local 169.254.169.254 reachability, MTU settings)
- Verify no proxy or firewall is cutting off the response mid-transfer
- If persistent, check DigitalOcean status page for metadata service incidents
Defensive patterns
Strategy: retry
Try / catch
meta, err := getMetadata(url)
if err != nil {
if strings.Contains(err.Error(), "failed to read metadata") {
// transient IO error: retry with backoff
}
} Prevention
- Set a client timeout and retry once or twice on body read failures
- Keep link-local (169.254.169.254) traffic free of proxies and MTU hacks
- Cache metadata results so transient read failures are tolerable
- Watch DigitalOcean status for metadata service incidents
When it happens
Trigger: io.ReadAll(resp.Body) returns an error when reading the 200 response from the droplet metadata endpoint — typically a dropped connection, read timeout, or malformed/chunked transfer abort.
Common situations: Flaky networking inside the droplet; metadata service under load closing connections; MTU/link-local issues truncating the response; container networking edge cases.
Related errors
- droplet metadata returned non-200 status code: %d
- failed to load AWS config: %w
- failed to get local-ipv4 address from ec2 metadata: %w
- error querying DigitalOcean droplet ID: %w
- reading primary MAC address from ec2 metadata: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/fabd458bcdc32ab6.
Report an issue: GitHub.