AlistGo/alist · error

wrong md5 hash

Error message

wrong md5 hash

What it means

When the optional md5 field in metadata is non-empty, it must be exactly 32 lowercase-hex-decodable characters (a canonical MD5 digest). hex.DecodeString failing or a length != 32 yields 'wrong md5 hash'. This guards the integrity chain: the driver later compares this stored digest against chunks it reads.

Source

Thrown at drivers/chunker/util.go:243

	var meta metadataJSON
	if err := json.Unmarshal(data, &meta); err != nil {
		return nil, err
	}
	if meta.Version == nil || meta.Size == nil || meta.ChunkNum == nil {
		return nil, errors.New("missing required field")
	}
	if *meta.Version < 1 {
		return nil, errors.New("wrong version")
	}
	if *meta.Size < 0 {
		return nil, errors.New("negative file size")
	}
	if *meta.ChunkNum < 1 || *meta.ChunkNum > maxSafeChunkNumber {
		return nil, errors.New("wrong number of chunks")
	}
	if meta.MD5 != "" {
		if _, err := hex.DecodeString(meta.MD5); err != nil || len(meta.MD5) != 32 {
			return nil, errors.New("wrong md5 hash")
		}
	}
	if meta.SHA1 != "" {
		if _, err := hex.DecodeString(meta.SHA1); err != nil || len(meta.SHA1) != 40 {
			return nil, errors.New("wrong sha1 hash")
		}
	}
	if *meta.Version > chunkerMetadataVerion {
		return nil, errors.New("unknown metadata version")
	}
	return &chunkMetadata{
		Version: *meta.Version,
		Size:    *meta.Size,
		NChunks: *meta.ChunkNum,
		MD5:     meta.MD5,
		SHA1:    meta.SHA1,
		XactID:  meta.XactID,
	}, nil

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Remove the incorrect md5 value from the metadata file (empty string is allowed and skips the check), or set it to the correct 32-char lowercase hex MD5
  2. Prefer regenerating metadata by re-uploading the file through the driver
  3. If your fork stores digests differently, keep the field empty rather than abusing it

Example fix

// before (metadata file content)
{"ver":1,"size":1024,"nchunks":2,"md5":"<40-char sha1>"}
// after
{"ver":1,"size":1024,"nchunks":2,"md5":"<32-char md5 hex>"}
Defensive patterns

Strategy: type-guard

Validate before calling

if meta.MD5 != "" {
    if _, err := hex.DecodeString(meta.MD5); err != nil || len(meta.MD5) != 32 {
        return fmt.Errorf("md5 must be 32 hex chars or empty")
    }
}

Type guard

func isValidMD5Field(s string) bool {
    if s == "" { return true }
    _, err := hex.DecodeString(s)
    return err == nil && len(s) == 32
}

Prevention

When it happens

Trigger: Metadata containing "md5":"deadbeef" (too short), mixed-case or non-hex characters, or a digest from a different algorithm (e.g. a 40-char SHA1 put in the md5 field). Raised when reading a chunked file with such metadata.

Common situations: Metadata written by scripts using SHA1/SHA256 in the md5 slot; uppercase hex digests; truncation of the field; copy-paste errors.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/5eabd5fdf0783a4b. Report an issue: GitHub.