{"record":{"id":"1ebb0e74136b6796","repo":"kubernetes/kops","slug":"cannot-interpret-q-value-as-v1-duration","errorCode":null,"errorMessage":"cannot interpret %q value as v1.Duration","messagePattern":"cannot interpret %q value as v1\\.Duration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/reflectutils/access.go","lineNumber":281,"sourceCode":"\t\tfdName, found := envVarType.FieldByName(\"Name\")\n\t\tif !found {\n\t\t\treturn fmt.Errorf(\"field Name not found in %T\", newV.Interface())\n\t\t}\n\t\tfdValue, found := envVarType.FieldByName(\"Value\")\n\t\tif !found {\n\t\t\treturn fmt.Errorf(\"field Value not found in %T\", newV.Interface())\n\t\t}\n\n\t\tname, value, hasValue := strings.Cut(newValue, \"=\")\n\t\tnewV.FieldByIndex(fdName.Index).SetString(name)\n\t\tif hasValue {\n\t\t\tnewV.FieldByIndex(fdValue.Index).SetString(value)\n\t\t}\n\n\tcase \"v1.Duration\":\n\t\tduration, err := time.ParseDuration(newValue)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot interpret %q value as v1.Duration\", newValue)\n\t\t}\n\t\tnewV = reflect.ValueOf(metav1.Duration{Duration: duration})\n\n\tcase \"resource.Quantity\":\n\t\tquantity, err := resource.ParseQuantity(newValue)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot interpret %q value as resource.Quantity\", newValue)\n\t\t}\n\t\tnewV = reflect.ValueOf(quantity)\n\n\tdefault:\n\t\t// This handles enums and other simple conversions\n\t\tnewV = reflect.ValueOf(newValue)\n\t\tif newV.Type().ConvertibleTo(v.Type()) {\n\t\t\tnewV = newV.Convert(v.Type())\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"unhandled type %q\", t)\n\t\t}","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/reflectutils/access.go#L263-L299","documentation":"When a field is tagged as metav1.Duration (\"v1.Duration\"), setType parses the string with time.ParseDuration. Any string that is not a Go duration literal (e.g. missing unit) produces this error. It tells you the supplied value is not a valid duration for the field.","triggerScenarios":"`kops set cluster spec.kubelet.nodeLeaseDurationSeconds=5m` style calls on duration-tagged fields (e.g. kube-dns, node-problem-detector settings) with strings like \"300\", \"5\", or \"forever\" — time.ParseDuration requires a unit.","commonSituations":"Users copy seconds values from Kubernetes docs into duration fields, forgetting Go duration syntax; empty values from templates; locale-specific formats like \"1h30\" (missing m).","solutions":["Use time.ParseDuration syntax with units: \"300s\", \"5m\", \"1h30m\"","For a plain seconds number, check whether the field is actually an int and pass 300 instead of \"300s\"","Validate the value locally with `go` time.ParseDuration before running the set command"],"exampleFix":"// before\nkops set cluster spec.kubelet.evictionHard=\"nodefs.available<10\"\n// duration example before\nkops set ... spec.nodeProblemDetector.monitorPeriod=30\n// after\nkops set ... spec.nodeProblemDetector.monitorPeriod=30s","handlingStrategy":"validation","validationCode":"d := \"30s\"\nif _, err := time.ParseDuration(d); err != nil {\n\treturn fmt.Errorf(\"invalid duration %q: %v\", d, err)\n}","typeGuard":"func isValidDuration(s string) bool { _, err := time.ParseDuration(s); return err == nil }","tryCatchPattern":"if err := doSet(); err != nil && strings.Contains(err.Error(), \"as v1.Duration\") {\n\t// retry with corrected duration string, e.g. append \"s\"\n}","preventionTips":["Always include a time unit (s/m/h) in duration values","Validate durations with time.ParseDuration before applying","Remember these are Go durations, not plain seconds"],"tags":["duration","value-parsing","go"],"backgroundTag":"invalid-duration-format","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"}