{"record":{"id":"86604cbe76cc6fc7","repo":"kubernetes/kops","slug":"reading-actual-user-data-w","errorCode":null,"errorMessage":"reading actual user-data: %w","messagePattern":"reading actual user-data: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"upup/pkg/fi/cloudup/scalewaytasks/instance.go","lineNumber":425,"sourceCode":"\tif actualServer.Image.ID != localImage.ID {\n\t\treturn true, nil\n\t}\n\treturn false, nil\n}\n\nfunc checkUserDataDifferences(c *fi.CloudupContext, cloud scaleway.ScwCloud, actualServer *instance.Server, expectedUserData *fi.Resource) (bool, error) {\n\tactualUserData, err := cloud.InstanceService().GetServerUserData(&instance.GetServerUserDataRequest{\n\t\tZone:     actualServer.Zone,\n\t\tServerID: actualServer.ID,\n\t\tKey:      \"cloud-init\",\n\t}, scw.WithContext(c.Context()))\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"getting actual user-data: %w\", err)\n\t}\n\n\tactualUserDataBytes, err := io.ReadAll(actualUserData)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"reading actual user-data: %w\", err)\n\t}\n\texpectedUserDataBytes, err := fi.ResourceAsBytes(*expectedUserData)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"reading expected user-data: %w\", err)\n\t}\n\n\tif sha256.Sum256(actualUserDataBytes) != sha256.Sum256(expectedUserDataBytes) {\n\t\treturn true, nil\n\t}\n\treturn false, nil\n}\n\nfunc imageLabelFromID(c *fi.CloudupContext, cloud scaleway.ScwCloud, id string) (string, error) {\n\tlocalImage, err := cloud.MarketplaceService().GetLocalImage(&marketplace.GetLocalImageRequest{\n\t\tLocalImageID: id,\n\t}, scw.WithContext(c.Context()))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"getting image from the marketplace: %w\", err)","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/scalewaytasks/instance.go#L407-L443","documentation":"During Scaleway instance reconciliation, kOps fetches the live 'cloud-init' user-data via the Scaleway instance API and reads its body into memory to hash-compare with the expected user-data. This error wraps any failure returned by io.ReadAll while draining the response reader (actualUserData). It means the API call succeeded (a reader was returned) but the streamed body could not be read, most often because the underlying HTTP body failed mid-transfer or the returned reader was in a bad state.","triggerScenarios":"io.ReadAll(actualUserData) fails after cloud.InstanceService().GetServerUserData(...) returned a reader for key 'cloud-init'; network interruption or TLS/reset while streaming the user-data body; server returns a truncated/aborted response body.","commonSituations":"Transient network failures or proxy timeouts during `kops update cluster` against Scaleway; flaky connectivity from CI runners; Scaleway API returning a connection reset mid-body; very large user-data payloads hitting intermediate timeouts.","solutions":["Re-run `kops update cluster` — this read is usually transient and succeeds on retry.","Verify network connectivity to api.scaleway.com (no proxy/VPN interference) and retry.","Set a shorter cluster spec / retry with SCW API env defaults; check https://status.scaleway.com for API incidents.","If persistent, delete/recreate user-data on the server or use `kops replace` to force refresh."],"exampleFix":"// caller side retry instead of failing the whole reconcile\nvar actualUserDataBytes []byte\nfor attempt := 0; attempt < 3; attempt++ {\n    actualUserData, err := cloud.InstanceService().GetServerUserData(&instance.GetServerUserDataRequest{\n        Zone: actualServer.Zone, ServerID: actualServer.ID, Key: \"cloud-init\",\n    }, scw.WithContext(c.Context()))\n    if err != nil {\n        return false, fmt.Errorf(\"getting actual user-data: %w\", err)\n    }\n    actualUserDataBytes, err = io.ReadAll(actualUserData)\n    if err == nil {\n        break\n    }\n}","handlingStrategy":"retry","validationCode":"// ensure the server actually has cloud-init user-data before comparing\nreq := &instance.GetServerUserDataRequest{Zone: s.Zone, ServerID: s.ID, Key: \"cloud-init\"}\n// callers should wrap GetServerUserData + ReadAll in a bounded retry with backoff\nvar data []byte\nerr := retry.Do(3, func() error {\n    r, err := cloud.InstanceService().GetServerUserData(req, scw.WithContext(ctx))\n    if err != nil { return err }\n    data, err = io.ReadAll(r)\n    return err\n})","typeGuard":null,"tryCatchPattern":"if actualBytes, err := io.ReadAll(actualUserData); err != nil {\n    return false, fmt.Errorf(\"reading actual user-data: %w\", err) // retry at a higher level\n}","preventionTips":["Retry transient read failures with exponential backoff instead of failing the reconcile","Watch the Scaleway status page for API incidents before large applies","Avoid running applies over unstable networks/proxies; prefer CI with reliable egress"],"tags":["scaleway","io","user-data","network"],"backgroundTag":"io-read-failure","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"}