{"record":{"id":"7d737837eb557a39","repo":"kubernetes/kops","slug":"reading-file-v-w","errorCode":null,"errorMessage":"reading file %v: %w","messagePattern":"reading file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops-controller/pkg/controllerclientset/clientset.go","lineNumber":64,"sourceCode":"\ntype client struct {\n\tvfsContext         *vfs.VFSContext\n\tclusterBasePath    vfs.Path\n\tclusterName        string\n\tclusterKeystore    fi.CAStore\n\tclusterSecretStore fi.SecretStore\n}\n\n// GetCluster reads a cluster by name\nfunc (c *client) GetCluster(ctx context.Context, name string) (*kops.Cluster, error) {\n\tif name != c.clusterName {\n\t\treturn nil, fmt.Errorf(\"clientset bound to cluster %q, got cluster %q\", c.clusterName, name)\n\t}\n\n\tp := c.clusterBasePath.Join(\"config\")\n\tb, err := p.ReadFile(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"reading file %v: %w\", p, err)\n\t}\n\n\tgvk := kops.SchemeGroupVersion.WithKind(\"Cluster\")\n\tobject, _, err := kopscodecs.Decode(b, &gvk)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing %v: %w\", p, err)\n\t}\n\n\tcluster, ok := object.(*kops.Cluster)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unexpected kind for cluster, got %T, want kops.Cluster\", object)\n\t}\n\treturn cluster, nil\n}\n\n// VFSContext returns a VFSContext.\nfunc (c *client) VFSContext() *vfs.VFSContext {\n\treturn c.vfsContext","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops-controller/pkg/controllerclientset/clientset.go#L46-L82","documentation":"GetCluster builds the path <clusterBasePath>/config and reads the cluster's serialized Cluster manifest; any read error (other than the name mismatch above) is wrapped as this message. The controller-side clientset is file-backed, so a missing or unreadable config file surfaces here.","triggerScenarios":"p.ReadFile(ctx) fails in GetCluster — file absent, permission denied, or mount unavailable; invoked from RunGetAll/RunGetClusters via GetCluster.","commonSituations":"Wrong state-store/base path configuration so the cluster config file isn't where expected; cluster deleted or renamed; controller pod lost access to the mounted state directory.","solutions":["Verify the cluster config file exists at the printed path (state store layout: <base>/cluster/config)","Check permissions and volume mounts providing the state directory","Confirm the cluster name and base path configuration (clusterBasePath) are correct","Restore/recreate the cluster config if it was deleted"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// pre-check that the cluster config file exists\np := clusterBasePath.Join(\"config\")\nif _, err := os.Stat(string(p)); os.IsNotExist(err) {\n\treturn fmt.Errorf(\"cluster config missing at %s\", p)\n}","typeGuard":null,"tryCatchPattern":"cluster, err := clientset.GetCluster(ctx, name)\nif err != nil {\n\tif strings.Contains(err.Error(), \"reading file\") {\n\t\t// path missing/unreadable: check state store config\n\t\treturn err\n\t}\n\treturn err\n}","preventionTips":["Verify state-store base path config before starting the controller","Back up cluster config files; never hand-delete them","Ensure state directory mounts survive pod rescheduling"],"tags":["file-io","state-store","cluster-config"],"backgroundTag":"file-read-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"}