{"record":{"id":"d188477fd52ad080","repo":"kubernetes/kops","slug":"unknown-hash-algorithm-q","errorCode":null,"errorMessage":"unknown hash algorithm: %q","messagePattern":"unknown hash algorithm: %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/hashing/hash.go","lineNumber":83,"sourceCode":"\tcase HashAlgorithmSHA256:\n\t\treturn sha256.New()\n\t}\n\n\tklog.Exitf(\"Unknown hash algorithm: %v\", ha)\n\treturn nil\n}\n\nfunc (ha HashAlgorithm) FromString(s string) (*Hash, error) {\n\tvar l int\n\tswitch ha {\n\tcase HashAlgorithmMD5:\n\t\tl = 32\n\tcase HashAlgorithmSHA1:\n\t\tl = 40\n\tcase HashAlgorithmSHA256:\n\t\tl = 64\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown hash algorithm: %q\", ha)\n\t}\n\n\tif len(s) != l {\n\t\treturn nil, fmt.Errorf(\"invalid %q hash - unexpected length %d\", ha, len(s))\n\t}\n\n\thashValue, err := hex.DecodeString(s)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid hash %q - not hex\", s)\n\t}\n\treturn &Hash{Algorithm: ha, HashValue: hashValue}, nil\n}\n\nfunc MustFromString(s string) *Hash {\n\th, err := FromString(s)\n\tif err != nil {\n\t\tklog.Fatalf(\"FromString(%q) failed with %v\", s, err)\n\t}","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/hashing/hash.go#L65-L101","documentation":"HashAlgorithm.FromString in util/pkg/hashing parses a hex-encoded hash string into a Hash for the given algorithm. The method only knows md5 (32 hex chars), sha1 (40) and sha256 (64); if the HashAlgorithm receiver holds any other value, there is no expected length and it returns this error. It guards against typos or uninitialized algorithm fields in asset/hash configuration.","triggerScenarios":"Calling FromString (directly or via GetHash/findHash/buildFileAsset/Add) with a HashAlgorithm value outside {\"md5\",\"sha1\",\"sha256\"} — e.g. hashing.HashAlgorithm(\"sha512\"), hashing.HashAlgorithm(\"\"), a misspelled \"sha-256\", or a value deserialized from user config (kops cluster spec hash fields) without validation.","commonSituations":"Typo in a cluster spec or asset config writing \"SHA256\"/\"sha-256\" instead of \"sha256\" (the constants are lowercase, case-sensitive); code defaulting to sha512 because it sounded stronger; an empty algorithm string from partially parsed \"sha256:abcdef\"-style strings where the prefix split failed; tests constructing HashAlgorithm from raw YAML/JSON input.","solutions":["Use the exported constants hashing.HashAlgorithmMD5, HashAlgorithmSHA1, or HashAlgorithmSHA256 instead of string literals","If parsing \"algo:hex\" strings, normalize the prefix and map it explicitly to a supported constant before calling FromString","Fix the casing/spelling: the algorithm must be exactly \"md5\", \"sha1\", or \"sha256\" (lowercase)","Prefer sha256 for new assets — md5/sha1 exist for legacy compatibility only"],"exampleFix":"// before\nalgo := hashing.HashAlgorithm(strings.Split(s, \":\")[0]) // \"SHA256\" from config\nh, err := algo.FromString(hex)\n// after\nvar algo hashing.HashAlgorithm\nswitch strings.ToLower(strings.Split(s, \":\")[0]) {\ncase \"md5\": algo = hashing.HashAlgorithmMD5\ncase \"sha1\": algo = hashing.HashAlgorithmSHA1\ncase \"sha256\": algo = hashing.HashAlgorithmSHA256\ndefault: return fmt.Errorf(\"unsupported hash algorithm in config\")\n}\nh, err := algo.FromString(hex)","handlingStrategy":"validation","validationCode":"func validHashAlgo(a hashing.HashAlgorithm) bool {\n    switch a {\n    case hashing.HashAlgorithmMD5, hashing.HashAlgorithmSHA1, hashing.HashAlgorithmSHA256:\n        return true\n    }\n    return false\n}\n// call before FromString:\nif !validHashAlgo(algo) {\n    return fmt.Errorf(\"config: algorithm %q must be md5, sha1, or sha256\", algo)\n}","typeGuard":"func isKnownHashAlgorithm(a hashing.HashAlgorithm) bool {\n    return a == hashing.HashAlgorithmMD5 ||\n        a == hashing.HashAlgorithmSHA1 ||\n        a == hashing.HashAlgorithmSHA256\n}","tryCatchPattern":"h, err := algo.FromString(hexHash)\nif err != nil {\n    if strings.Contains(err.Error(), \"unknown hash algorithm\") {\n        return fmt.Errorf(\"bad hash algorithm %q in config (want md5|sha1|sha256): %w\", algo, err)\n    }\n    return err\n}","preventionTips":["Always use the exported HashAlgorithm constants, never raw strings from YAML/JSON","Remember the values are lowercase and case-sensitive: \"sha256\", not \"SHA256\" or \"sha-256\"","Validate hash algorithm fields in cluster configs at load time with a whitelist","Prefer sha256 for new assets; treat md5/sha1 as legacy-only"],"tags":["hashing","validation","assets","configuration"],"backgroundTag":"unknown-hash-algorithm","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"}