{"record":{"id":"e65b7bee6dd8391c","repo":"kubernetes/kops","slug":"evictionhard-w","errorCode":null,"errorMessage":"evictionHard: %w","messagePattern":"evictionHard: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodeup/pkg/model/kubelet.go","lineNumber":388,"sourceCode":"\t}\n\n\t// EventQPS is the legacy kops field; EventRecordQPS is the newer alias\n\t// matching the kubelet config field name. Preserve historical precedence\n\t// where EventQPS overrides EventRecordQPS when both are set.\n\tif kubeletConfig.EventQPS != nil {\n\t\tcc.EventRecordQPS = kubeletConfig.EventQPS\n\t}\n\n\tif b.NodeupConfig.ContainerdConfig.Address == nil {\n\t\tcc.ContainerRuntimeEndpoint = \"unix:///run/containerd/containerd.sock\"\n\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","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/nodeup/pkg/model/kubelet.go#L370-L406","documentation":"parseKeyValueList converts the kops CSV-style EvictionHard string (e.g. \"memory.available<100Mi,nodefs.available<10%\") into the map[string]string the kubelet config requires, splitting each pair on '<'. If any comma-separated entry lacks the '<' separator, parsing fails and the error is wrapped as \"evictionHard: %w\" with the detail \"invalid key/value pair ...\".","triggerScenarios":"kubeletConfiguration -> parseKeyValueList(*kubeletConfig.EvictionHard, \"<\") returns an error because an entry in spec.kubelet.evictionHard contains no '<' character.","commonSituations":"Typo in the cluster spec such as \"memory.available=100Mi\" (used '=' instead of '<'); a stray comma producing an empty or separator-less entry; copying evictionSoft syntax (which uses '<') but writing grace-period style '=' pairs into evictionHard.","solutions":["Inspect the wrapped message for the offending pair %q and add the '<' separator (e.g. memory.available<100Mi)","Run kops edit cluster and fix spec.kubelet.evictionHard entries","Remember each pair must be key<value, comma-separated, no trailing commas","Re-run kops update cluster / nodeup after fixing"],"exampleFix":"// before\nkubelet:\n  evictionHard: \"memory.available=100Mi\"\n// after\nkubelet:\n  evictionHard: \"memory.available<100Mi,nodefs.available<10%\"","handlingStrategy":"validation","validationCode":"func validEvictionHard(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}\n// assert validEvictionHard(cluster.Spec.Kubelet.EvictionHard) before update","typeGuard":null,"tryCatchPattern":"cfg, err := kubeletConfiguration(...)\nif err != nil && strings.Contains(err.Error(), \"evictionHard:\") {\n    return fmt.Errorf(\"fix spec.kubelet.evictionHard: each pair needs '<': %w\", err)\n}","preventionTips":["Always use key<value syntax for evictionHard/evictionSoft","Avoid trailing commas in the CSV string","Lint cluster specs for eviction fields before kops update"],"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"}