{"record":{"id":"0e316ef7c3f7e4f5","repo":"kubernetes/kops","slug":"evictionsoftgraceperiod-w","errorCode":null,"errorMessage":"evictionSoftGracePeriod: %w","messagePattern":"evictionSoftGracePeriod: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodeup/pkg/model/kubelet.go","lineNumber":399,"sourceCode":"\t} else {\n\t\tcc.ContainerRuntimeEndpoint = \"unix://\" + fi.ValueOf(b.NodeupConfig.ContainerdConfig.Address)\n\t}\n\n\tif kubeletConfig.EvictionHard != nil {\n\t\tevictionHard, err := parseKeyValueList(*kubeletConfig.EvictionHard, \"<\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"evictionHard: %w\", err)\n\t\t}\n\t\tcc.EvictionHard = evictionHard\n\t}\n\tevictionSoft, err := parseKeyValueList(kubeletConfig.EvictionSoft, \"<\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"evictionSoft: %w\", err)\n\t}\n\tcc.EvictionSoft = evictionSoft\n\tevictionSoftGracePeriod, err := parseKeyValueList(kubeletConfig.EvictionSoftGracePeriod, \"=\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"evictionSoftGracePeriod: %w\", err)\n\t}\n\tcc.EvictionSoftGracePeriod = evictionSoftGracePeriod\n\tevictionMinimumReclaim, err := parseKeyValueList(kubeletConfig.EvictionMinimumReclaim, \"=\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"evictionMinimumReclaim: %w\", err)\n\t}\n\tcc.EvictionMinimumReclaim = evictionMinimumReclaim\n\n\tfeatureGates, err := parseFeatureGates(kubeletConfig.FeatureGates)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"featureGates: %w\", err)\n\t}\n\tcc.FeatureGates = featureGates\n\n\tif kubeletConfig.EnforceNodeAllocatable != \"\" {\n\t\tcc.EnforceNodeAllocatable = strings.Split(kubeletConfig.EnforceNodeAllocatable, \",\")\n\t}\n","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/nodeup/pkg/model/kubelet.go#L381-L417","documentation":"EvictionSoftGracePeriod is parsed with parseKeyValueList using '=' as separator (e.g. \"memory.available=30s\"). If any comma-separated entry lacks '=', the parse fails and the error is wrapped as \"evictionSoftGracePeriod: %w\".","triggerScenarios":"kubeletConfiguration -> parseKeyValueList(kubeletConfig.EvictionSoftGracePeriod, \"=\") fails because an entry has no '=' separator.","commonSituations":"Using '<' (the evictionSoft separator) by mistake in grace period values; omitting the value (\"memory.available=\" would still pass Cut, but \"memory.available\" alone fails); copy-paste across fields with different separator conventions.","solutions":["Ensure every entry is key=value form, e.g. memory.available=30s","Check the wrapped %q pair in the message and add the '=' separator","Do not reuse '<'-style threshold strings in this field","Re-apply the cluster config and re-run nodeup"],"exampleFix":"// before\nkubelet:\n  evictionSoftGracePeriod: \"memory.available<30s\"\n// after\nkubelet:\n  evictionSoftGracePeriod: \"memory.available=30s\"","handlingStrategy":"validation","validationCode":"func validGracePeriods(s string) bool {\n    if s == \"\" { return true }\n    for _, kv := range strings.Split(s, \",\") {\n        if !strings.Contains(kv, \"=\") { return false }\n    }\n    return true\n}","typeGuard":null,"tryCatchPattern":"if _, err := parseKeyValueList(cfg.EvictionSoftGracePeriod, \"=\"); err != nil {\n    return fmt.Errorf(\"evictionSoftGracePeriod must be key=value pairs: %w\", err)\n}","preventionTips":["Grace period entries use '=', not '<'","Include a value after '=' for every key","Document separator conventions per field in your cluster templates"],"tags":["kubelet","eviction","config-parsing"],"backgroundTag":"kubelet-eviction-config-invalid","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"}