{"record":{"id":"951e82b60bb925b6","repo":"kubernetes/kops","slug":"failed-to-list-cluster-ssh-keys-w","errorCode":null,"errorMessage":"failed to list cluster ssh keys: %w","messagePattern":"failed to list cluster ssh keys: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/scaleway/cloud.go","lineNumber":483,"sourceCode":"\tif err != nil {\n\t\tif instanceGroupName != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to list cluster servers named %q: %w\", *instanceGroupName, err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to list cluster servers: %w\", err)\n\t}\n\treturn servers.Servers, nil\n}\n\nfunc (s *scwCloudImplementation) GetClusterSSHKeys(clusterName string) ([]*iam.SSHKey, error) {\n\tclusterSSHKeys := []*iam.SSHKey(nil)\n\tallSSHKeys, err := s.iamAPI.ListSSHKeys(&iam.ListSSHKeysRequest{}, scw.WithAllPages())\n\tfor _, sshkey := range allSSHKeys.SSHKeys {\n\t\tif strings.HasPrefix(sshkey.Name, fmt.Sprintf(\"kubernetes.%s-\", clusterName)) {\n\t\t\tclusterSSHKeys = append(clusterSSHKeys, sshkey)\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list cluster ssh keys: %w\", err)\n\t}\n\treturn clusterSSHKeys, nil\n}\n\nfunc (s *scwCloudImplementation) GetClusterVolumes(clusterName string) ([]*instance.Volume, error) {\n\tvolumes, err := s.instanceAPI.ListVolumes(&instance.ListVolumesRequest{\n\t\tZone: s.zone,\n\t\tTags: []string{TagClusterName + \"=\" + clusterName},\n\t}, scw.WithAllPages())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list cluster volumes: %w\", err)\n\t}\n\treturn volumes.Volumes, nil\n}\n\nfunc (s *scwCloudImplementation) GetServerIP(serverID string, zone scw.Zone) (string, error) {\n\tregion, err := zone.Region()\n\tif err != nil {","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/scaleway/cloud.go#L465-L501","documentation":"Wrap-around error returned by GetClusterSSHKeys when the Scaleway IAM API ListSSHKeys (paginated) fails. The function filters returned keys by the `kubernetes.<clusterName>-` name prefix, so this error fires only on the API call itself, not on finding zero keys. The underlying SDK error is preserved with %w.","triggerScenarios":"iam.API.ListSSHKeys failure: invalid/expired IAM credentials, IAM policy denying ssh_keys list permission, project ID mismatch, network error, or Scaleway IAM API outage/rate limit.","commonSituations":"Service account token or secret key rotated without updating kops config; IAM policy scoped too narrowly for the kops principal; transient IAM API outage during cluster validation.","solutions":["Validate credentials with `scw iam ssh-key list` using the same access/secret keys kops uses.","Check the IAM policy/applications permissions for the principal: it needs iam_ssh_keys list rights.","Confirm the project ID matches the project holding the cluster SSH keys.","If the IAM API returns 429/5xx, retry with backoff after checking Scaleway status."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// preflight: can this principal list SSH keys?\nimport \"github.com/scaleway/scaleway-sdk-go/services/iam\"\napi := iam.NewAPI(client)\nif _, err := api.ListSSHKeys(&iam.ListSSHKeysRequest{PageSize: scw.Uint32Ptr(1)}); err != nil {\n  return fmt.Errorf(\"iam ssh-key list preflight failed: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := kopsValidateCluster(); err != nil {\n  var scwErr *scw.Error\n  if errors.As(err, &scwErr) && scwErr.StatusCode == 403 {\n    // fix IAM policy before retrying\n  }\n  return err\n}","preventionTips":["Grant the kops principal explicit iam_ssh_keys list permission.","Rotate credentials centrally and update kops env/config immediately.","Use a dedicated IAM application/policy for kops with least privilege including IAM read."],"tags":["scaleway","iam","ssh-keys","api-error"],"backgroundTag":"scaleway-api-request-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"}