{"record":{"id":"021bf7dbab0e9a9b","repo":"kubernetes/kops","slug":"invalid-q-hash-unexpected-length-d","errorCode":null,"errorMessage":"invalid %q hash - unexpected length %d","messagePattern":"invalid %q hash - unexpected length (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/hashing/hash.go","lineNumber":87,"sourceCode":"\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}\n\treturn h\n}\n\nfunc FromString(s string) (*Hash, error) {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/hashing/hash.go#L69-L105","documentation":"FromString validates that a hash string for a given algorithm has the expected length (MD5=32, SHA1=40, SHA256=64) before hex-decoding it. This error is thrown when the string length does not match the declared algorithm's digest size. It indicates the hash string was truncated, padded, or paired with the wrong algorithm prefix.","triggerScenarios":"Calling HashAlgorithm.FromString (or FromString via length-prefixed paths like buildFileAsset, FindCNIAssets, Add) with e.g. hashAlgorithmSHA256.FromString(\"abc123...\") where the string is 40 chars instead of 64, or a partially copied/truncated hash in an asset manifest.","commonSituations":"Manually editing cluster spec assets or file URLs and pasting a SHA1 hash into a sha256 field; copying hashes from docs for a different algorithm version; downloading truncated hash files; CNI manifest hashes updated for one algorithm but not the other.","solutions":["Count the hash string length and use the matching algorithm prefix (32=md5, 40=sha1, 64=sha256)","Recompute the hash with `sha256sum <file>` and replace the value in the asset/manifest","If the algorithm is unknown, use FromString on the bare string (hash.go:106) which infers the algorithm from length"],"exampleFix":"// before\nh, err := hashing.HashAlgorithmSHA256.FromString(\"d41d8cd98f00b204e9800998ecf8427e\") // 32 chars\n// after\nh, err := hashing.HashAlgorithmMD5.FromString(\"d41d8cd98f00b204e9800998ecf8427e\")","handlingStrategy":"validation","validationCode":"func isValidHashFor(algo hashing.HashAlgorithm, s string) bool {\n\tvar l int\n\tswitch algo {\n\tcase hashing.HashAlgorithmMD5: l = 32\n\tcase hashing.HashAlgorithmSHA1: l = 40\n\tcase hashing.HashAlgorithmSHA256: l = 64\n\tdefault: return false\n\t}\n\tif len(s) != l { return false }\n\t_, err := hex.DecodeString(s)\n\treturn err == nil\n}","typeGuard":"func isHex(s string) bool {\n\t_, err := hex.DecodeString(s)\n\treturn err == nil\n}","tryCatchPattern":"h, err := hashing.HashAlgorithmSHA256.FromString(s)\nif err != nil {\n\tif strings.Contains(err.Error(), \"unexpected length\") {\n\t\treturn fmt.Errorf(\"hash %q is not a sha256 digest (want 64 hex chars)\", s)\n\t}\n\treturn err\n}","preventionTips":["Generate hashes with sha256sum/sha1sum/md5sum so length and hex-ness are guaranteed","Keep algorithm name and hash value paired in one structure, never edited separately","Validate asset manifests at load time before use","Never hand-edit hash values; regenerate them from the artifact"],"tags":["hashing","validation","input-length"],"backgroundTag":"hash-length-mismatch","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"}