{"record":{"id":"8f3ca4de6656d58b","repo":"golang/go","slug":"crypto-md5-invalid-hash-state-identifier","errorCode":null,"errorMessage":"crypto/md5: invalid hash state identifier","messagePattern":"crypto/md5: invalid hash state identifier","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/md5/md5.go","lineNumber":83,"sourceCode":"func (d *digest) MarshalBinary() ([]byte, error) {\n\treturn d.AppendBinary(make([]byte, 0, marshaledSize))\n}\n\nfunc (d *digest) AppendBinary(b []byte) ([]byte, error) {\n\tb = append(b, magic...)\n\tb = byteorder.BEAppendUint32(b, d.s[0])\n\tb = byteorder.BEAppendUint32(b, d.s[1])\n\tb = byteorder.BEAppendUint32(b, d.s[2])\n\tb = byteorder.BEAppendUint32(b, d.s[3])\n\tb = append(b, d.x[:d.nx]...)\n\tb = append(b, make([]byte, len(d.x)-d.nx)...)\n\tb = byteorder.BEAppendUint64(b, d.len)\n\treturn b, nil\n}\n\nfunc (d *digest) UnmarshalBinary(b []byte) error {\n\tif len(b) < len(magic) || string(b[:len(magic)]) != magic {\n\t\treturn errors.New(\"crypto/md5: invalid hash state identifier\")\n\t}\n\tif len(b) != marshaledSize {\n\t\treturn errors.New(\"crypto/md5: invalid hash state size\")\n\t}\n\tb = b[len(magic):]\n\tb, d.s[0] = consumeUint32(b)\n\tb, d.s[1] = consumeUint32(b)\n\tb, d.s[2] = consumeUint32(b)\n\tb, d.s[3] = consumeUint32(b)\n\tb = b[copy(d.x[:], b):]\n\tb, d.len = consumeUint64(b)\n\td.nx = int(d.len % BlockSize)\n\treturn nil\n}\n\nfunc consumeUint64(b []byte) ([]byte, uint64) {\n\treturn b[8:], byteorder.BEUint64(b[0:8])\n}","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/md5/md5.go#L65-L101","documentation":"Returned by md5 digest.UnmarshalBinary when the input is shorter than the magic prefix or the prefix does not equal md5's magic constant. The magic identifies the bytes as MD5 state; a mismatch means the data is not a valid MD5 serialized state (or belongs to a different hash).","triggerScenarios":"Calling UnmarshalBinary on an MD5 digest with bytes from another hash (SHA-1, SHA-256), corrupted bytes, an empty buffer, or a buffer shorter than the magic prefix.","commonSituations":"Persisting MD5 hash state and reloading it with corrupted or empty data; sending hash state over a protocol where another hash writes the same field; downgrading code that previously used a stronger hash and forgetting to migrate the stored state.","solutions":["Verify the bytes were produced by md5's MarshalBinary on the same Go version.","If migrating from another hash, re-hash from the original input.","Check len(b) >= len(magic) before calling and treat shorter buffers as corrupt.","Prefer SHA-256 over MD5 for any new code (MD5 is cryptographically broken)."],"exampleFix":"// before\nd.UnmarshalBinary(sha1StateBytes) // wrong magic -> error\n// after\nd.UnmarshalBinary(md5StateBytes) // produced by md5 MarshalBinary","handlingStrategy":"validation","validationCode":"if len(b) < len(magic) || string(b[:len(magic)]) != magic {\n    return errors.New(\"not MD5 marshaled state\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify bytes were produced by md5's MarshalBinary on the same Go version.","Prefer SHA-256 over MD5 for any new code.","Re-hash from the original input when migrating from another hash."],"tags":["crypto","hash","md5","serialization","go-stdlib"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}