{"record":{"id":"79d219f515130595","repo":"kubernetes/kops","slug":"not-valid-md5-sum-q","errorCode":null,"errorMessage":"not valid MD5 sum: %q","messagePattern":"not valid MD5 sum: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/azureblob.go","lineNumber":98,"sourceCode":"\n// PreferredHash returns the hash of the file contents, with the preferred hash algorithm.\nfunc (p *AzureBlobPath) PreferredHash() (*hashing.Hash, error) {\n\treturn p.Hash(hashing.HashAlgorithmMD5)\n}\n\n// Hash gets the hash, or nil if the hash cannot be (easily) computed.\nfunc (p *AzureBlobPath) Hash(a hashing.HashAlgorithm) (*hashing.Hash, error) {\n\tif a != hashing.HashAlgorithmMD5 {\n\t\treturn nil, nil\n\t}\n\n\tif p.md5Hash == \"\" {\n\t\treturn nil, nil\n\t}\n\n\tmd5Bytes, err := base64.StdEncoding.DecodeString(p.md5Hash)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"not valid MD5 sum: %q\", p.md5Hash)\n\t}\n\n\treturn &hashing.Hash{Algorithm: hashing.HashAlgorithmMD5, HashValue: md5Bytes}, nil\n}\n\n// Path returns a string representing the full path.\nfunc (p *AzureBlobPath) Path() string {\n\treturn fmt.Sprintf(\"azureblob://%s/%s/%s\", p.account, p.container, p.key)\n}\n\n// String implements fmt.Stringer; returns Path() so %s renders the full URL.\nfunc (p *AzureBlobPath) String() string {\n\treturn p.Path()\n}\n\n// Join returns a new path that joins the current path and given relative paths.\nfunc (p *AzureBlobPath) Join(relativePath ...string) Path {\n\targs := []string{p.key}","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/azureblob.go#L80-L116","documentation":"AzureBlobPath.Hash returns the MD5 of a stored blob. Azure stores content MD5 as a base64 string; this code base64-decodes it before returning. If the stored md5Hash string is not valid base64 (or not 16 decoded bytes), the library refuses to produce a hash and throws `not valid MD5 sum: %q`.","triggerScenarios":"Reading a blob whose ContentMD5 property is corrupt, empty-but-set, or was written by a tool that stored a hex-encoded or non-base64 MD5 string; calling Hash (or PreferredHash) on such a VFSPath.","commonSituations":"Blobs uploaded by third-party tools (azcopy configs, terraform, custom scripts) that wrote hex MD5 instead of base64; blobs uploaded without MD5 computed then patched with a malformed value; older Azure tooling version differences in how ContentMD5 is set.","solutions":["Re-upload the blob with a correct base64-encoded MD5 (openssl dgst -md5 -binary file | openssl base64).","Clear the blob's ContentMD5 property so Hash returns nil,nil instead of failing on invalid data.","If the value is hex-encoded, convert it to base64 before comparing or patch the blob metadata.","Set the ContentMD5 header explicitly at upload time so Azure validates and stores a proper base64 MD5."],"exampleFix":"// before: hex md5 stored on blob -> \"not valid MD5 sum: \\\"5d41402abc...\\\"\"\n// after: set proper base64 md5 on upload\nmd5 := md5.Sum(data)\nh.Header.Set(\"x-ms-blob-content-md5\", base64.StdEncoding.EncodeToString(md5[:]))","handlingStrategy":"validation","validationCode":"import (\n    \"encoding/base64\"\n    \"encoding/hex\"\n)\n\n// Validate/normalize a stored MD5 string before calling Hash\nfunc validateMD5(s string) error {\n    if s == \"\" { return nil }\n    if b, err := base64.StdEncoding.DecodeString(s); err == nil && len(b) == 16 { return nil }\n    if b, err := hex.DecodeString(s); err == nil && len(b) == 16 { return nil } // hex variant\n    return fmt.Errorf(\"not a valid MD5: %q\", s)\n}","typeGuard":"func isValidBase64MD5(s string) bool {\n    if s == \"\" { return true } // treated as no-hash\n    b, err := base64.StdEncoding.DecodeString(s)\n    return err == nil && len(b) == 16\n}","tryCatchPattern":null,"preventionTips":["Always set x-ms-blob-content-md5 (base64) when uploading blobs to Azure","Never store hex-encoded MD5 in blob ContentMD5 properties","Scan existing buckets for blobs with malformed ContentMD5 and clear or re-upload them","Use PreferredHash/verify flow that tolerates nil hashes when MD5 is absent"],"tags":["azure","md5","hash","base64"],"backgroundTag":"invalid-md5-checksum","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"}