{"record":{"id":"9296fc06cc216c35","repo":"kubernetes/kops","slug":"listing-resources-for-v-w","errorCode":null,"errorMessage":"listing resources for %v: %w","messagePattern":"listing resources for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/dump/resourcedumper.go","lineNumber":201,"sourceCode":"\treturn gvrNamespaces, nil\n}\n\nfunc (d *resourceDumper) dumpGVRNamespaces(ctx context.Context, jobs chan gvrNamespace, results chan resourceDumpResult) {\n\tfor job := range jobs {\n\t\tvar lister dynamic.ResourceInterface\n\t\tif job.namespace != \"\" {\n\t\t\tlister = d.dynamicClient.Resource(job.gvr).Namespace(job.namespace)\n\t\t} else {\n\t\t\tlister = d.dynamicClient.Resource(job.gvr)\n\t\t}\n\t\tresourceList, err := lister.List(ctx, metav1.ListOptions{})\n\t\tif err != nil {\n\t\t\tvar statusErr *k8sErrors.StatusError\n\t\t\tif errors.As(err, &statusErr) && statusErr.ErrStatus.Code >= 400 && statusErr.ErrStatus.Code < 500 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tresults <- resourceDumpResult{\n\t\t\t\terr: fmt.Errorf(\"listing resources for %v: %w\", job, err),\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tresPath := path.Join(d.artifactsDir, \"cluster-info\", fmt.Sprintf(\"%v.%v\", job.String(), d.output))\n\t\terr = os.MkdirAll(path.Dir(resPath), 0755)\n\t\tif err != nil {\n\t\t\tresults <- resourceDumpResult{\n\t\t\t\terr: fmt.Errorf(\"creating directory %q: %w\", resPath, err),\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tresFile, err := os.Create(resPath)\n\t\tif err != nil {\n\t\t\tresults <- resourceDumpResult{\n\t\t\t\terr: fmt.Errorf(\"creating file %q: %w\", resPath, err),\n\t\t\t}\n\t\t\tcontinue\n\t\t}","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/dump/resourcedumper.go#L183-L219","documentation":"The worker dumpGVRNamespaces lists objects for each (GVR, namespace) job via the dynamic client. Client-side HTTP errors with status 4xx (e.g. 403 forbidden, 404 gone) are silently skipped; anything else — 5xx server errors, 429 throttling outside client rate limiting, timeouts, connection resets — is sent to the results channel wrapped as \"listing resources for %v: %w\". These are collected and joined by DumpResources, so one failing resource does not abort the whole dump.","triggerScenarios":"API server returns 5xx (etcd overload, apiserver crashloop), the context is cancelled mid-list, connection drops, or the client exhausts retries. Note 4xx StatusErrors are intentionally skipped, so this only fires for non-StatusError or 5xx/non-listed-code failures.","commonSituations":"Large clusters timing out on list (list cost too high for etcd); API server under memory pressure returning 500; caller cancelling ctx during dump; flaky network to the control plane; resource removed between discovery and list (usually skipped as 404, not this error).","solutions":["Read the wrapped cause: 5xx/timeouts usually mean server overload — retry with fewer concurrent workers or a larger context timeout.","Reduce resourceDumpConcurrency or the resource set (discovery is currently listing every namespaced GVR x every namespace).","Ensure the caller's context is not cancelled prematurely during the dump.","If a specific GVR consistently fails, check the API server/etcd logs for that resource's storage errors and fix or exclude the CRD."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// precondition: stable API server; e.g.\nif _, err := client.Discovery().ServerVersion(); err != nil {\n\treturn fmt.Errorf(\"API server unhealthy before dump: %w\", err)\n}\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute)\ndefer cancel()","typeGuard":"func isRetryableListError(err error) bool {\n\tif k8sErrors.IsServerTimeout(err) || k8sErrors.IsTooManyRequests(err) || k8sErrors.IsInternalError(err) {\n\t\treturn true\n\t}\n\tvar se *k8sErrors.StatusError\n\tif errors.As(err, &se) {\n\t\treturn se.ErrStatus.Code >= 500 // 4xx list failures are skipped by the dumper anyway\n\t}\n\treturn errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) == false && errors.Is(err, io.EOF)\n}","tryCatchPattern":"if err := dumper.DumpResources(ctx); err != nil {\n\tif isRetryableListError(err) {\n\t\t// 5xx/timeouts: back off, optionally reduce concurrency, retry\n\t}\n\tif errors.Is(err, context.Canceled) {\n\t\t// caller cancelled mid-dump: expected, not a dump defect\n\t}\n\treturn err\n}","preventionTips":["Use a context with a generous timeout for big clusters; lists of every GVR x namespace are expensive.","Keep resourceDumpConcurrency modest so etcd/apiserver aren't overwhelmed.","Monitor API server 5xx rates; retry the dump when the control plane is healthy.","Don't cancel the parent context mid-dump unless aborting is intended; partial results will be reported as joined errors."],"tags":["kubernetes","dynamic-client","list","network","timeout"],"backgroundTag":"kube-api-server-error","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"}