{"record":{"id":"266fe1eddd6d598e","repo":"k3s-io/k3s","slug":"cannot-use-current-data-for-s-field-is-not-setta","errorCode":null,"errorMessage":"cannot use current data for %s; field is not settable","messagePattern":"cannot use current data for (.+?); field is not settable","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"pkg/server/handlers/cert.go","lineNumber":124,"sourceCode":"\toldMeta := reflect.ValueOf(&oldControl.Runtime.ControlRuntimeBootstrap).Elem()\n\tnewMeta := reflect.ValueOf(&newControl.Runtime.ControlRuntimeBootstrap).Elem()\n\n\t// use the existing file if the new file does not exist or is empty\n\tfor _, field := range reflect.VisibleFields(oldMeta.Type()) {\n\t\tnewVal := newMeta.FieldByName(field.Name)\n\t\tinfo, err := os.Stat(newVal.String())\n\t\tif err != nil && !errors.Is(err, fs.ErrNotExist) {\n\t\t\terrs = append(errs, errors.WithMessage(err, field.Name))\n\t\t\tcontinue\n\t\t}\n\n\t\tif field.Tag.Get(\"rotate\") != \"true\" || info == nil || info.Size() == 0 {\n\t\t\tif newVal.CanSet() {\n\t\t\t\toldVal := oldMeta.FieldByName(field.Name)\n\t\t\t\tlogrus.Infof(\"Using current data for %s: %s\", field.Name, oldVal)\n\t\t\t\tnewVal.Set(oldVal)\n\t\t\t} else {\n\t\t\t\terrs = append(errs, fmt.Errorf(\"cannot use current data for %s; field is not settable\", field.Name))\n\t\t\t}\n\t\t}\n\t}\n\treturn errors.Join(errs...)\n}\n\n// validateBootstrap checks the new certs and keys to ensure that the cluster would function properly were they to be used.\n// - The new leaf CA certificates must be verifiable using the same root and intermediate certs as the current leaf CA certificates.\n// - The new service account signing key bundle must include the currently active signing key.\nfunc validateBootstrap(oldControl, newControl *config.Control) error {\n\terrs := []error{}\n\n\t// Use reflection to iterate over all of the bootstrap fields, checking files at each of the new paths.\n\toldMeta := reflect.ValueOf(&oldControl.Runtime.ControlRuntimeBootstrap).Elem()\n\tnewMeta := reflect.ValueOf(&newControl.Runtime.ControlRuntimeBootstrap).Elem()\n\n\tfor _, field := range reflect.VisibleFields(oldMeta.Type()) {\n\t\t// Only handle bootstrap fields tagged for rotation","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/server/handlers/cert.go#L106-L142","documentation":"When k3s rotates certificates or bootstraps with user-supplied certs, it walks the Control.Runtime cert/key fields with reflection. For each field whose new file is missing, empty, or not marked rotate:\"true\", it tries to carry over the existing value from the old struct (oldVal -> newVal). The copy requires the reflected field to be settable; if newVal was obtained through a non-addressable value or an unexported field, CanSet() is false and this error is recorded.","triggerScenarios":"Invoking certificate rotation (k3s certificate rotate) or passing a partial set of custom cert/key files in the cluster configuration while some Control.Runtime fields are not settable through reflection - e.g. the struct value was copied rather than addressed, or a field is unexported. The error is aggregated by errors.Join and returned from the rotation prep step.","commonSituations":"Operators supplying an incomplete custom certificate bundle (some files present, others absent/zero-byte) so the carry-over path is taken; or a k3s version change that altered Control.Runtime field composition so reflection hits a field it cannot set. Usually appears immediately when starting the rotate handler.","solutions":["Provide the complete set of custom certificate and key files referenced by your configuration, so no field needs its value carried over from the old struct.","If you intended full rotation, ensure every file meant to be regenerated is absent and fields are tagged rotate:true, then rerun k3s certificate rotate.","Check file sizes of everything under your cert directory; zero-byte files push fields onto the carry-over path.","If all files are complete and the error persists on the current release, report it upstream with your k3s version - the un-settable field is a code defect, not a config problem."],"exampleFix":"# before: partial bundle, some files missing\nsudo ls /etc/rancher/k3s/certs  # client-k3s-controller.crt absent -> carry-over path\n\n# after: complete bundle or none\nsudo k3s certificate rotate  # let k3s regenerate everything instead of mixing","handlingStrategy":"validation","validationCode":"// Before rotating, confirm every referenced cert/key file exists and is non-empty\nfor _, f := range certFiles {\n    fi, err := os.Stat(f)\n    if err != nil || fi.Size() == 0 {\n        log.Fatalf(\"missing or empty: %s\", f)\n    }\n}","typeGuard":null,"tryCatchPattern":"// Wrap the rotate call and surface the joined errors individually\nif err := validateBootstrap(oldControl, newControl); err != nil {\n    for _, e := range errors.Unwrap(err).([]error) { // errors.Join payload\n        if strings.Contains(e.Error(), \"field is not settable\") {\n            // config problem: supply complete cert set or report upstream\n        }\n    }\n}","preventionTips":["Supply complete custom cert bundles or none - never partial sets","Keep rotate:true tagging consistent with fields you expect k3s to regenerate","Test rotation on a staging cluster before production"],"tags":["certificates","reflection","rotation","tls"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}