{"record":{"id":"3643fb12cf3f26e0","repo":"AlistGo/alist","slug":"hash-type-not-supported","errorCode":null,"errorMessage":"hash type not supported","messagePattern":"hash type not supported","errorType":"exception","errorClass":"ErrUnsupported","httpStatus":null,"severity":"warning","filePath":"pkg/utils/hash.go","lineNumber":27,"sourceCode":"\t\"encoding/json\"\n\t\"errors\"\n\t\"hash\"\n\t\"io\"\n\t\"iter\"\n\n\t\"github.com/alist-org/alist/v3/internal/errs\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc GetMD5EncodeStr(data string) string {\n\treturn HashData(MD5, []byte(data))\n}\n\n//inspired by \"github.com/rclone/rclone/fs/hash\"\n\n// ErrUnsupported should be returned by filesystem,\n// if it is requested to deliver an unsupported hash type.\nvar ErrUnsupported = errors.New(\"hash type not supported\")\n\n// HashType indicates a standard hashing algorithm\ntype HashType struct {\n\tWidth   int\n\tName    string\n\tAlias   string\n\tNewFunc func(...any) hash.Hash\n}\n\nfunc (ht *HashType) MarshalJSON() ([]byte, error) {\n\treturn []byte(`\"` + ht.Name + `\"`), nil\n}\n\nfunc (ht *HashType) MarshalText() (text []byte, err error) {\n\treturn []byte(ht.Name), nil\n}\n\nvar (","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/pkg/utils/hash.go#L9-L45","documentation":"ErrUnsupported from pkg/utils/hash.go (inspired by rclone): a storage driver was asked for a hash type it cannot compute. The HashType registry (MD5, SHA1, SHA256, CRC32...) is generic, but individual drivers support only a subset.","triggerScenarios":"Requesting a hash type from a storage driver that doesn't implement it — e.g. asking an S3 driver for a hash type it doesn't map, or any driver whose Hash() returns this error for the given type.","commonSituations":"Code assumes every backend can produce MD5/SHA1; migrating config between backends where the preferred hash type differs; asking for a hash on a backend that only returns ETag.","solutions":["Query which hash types the driver supports before requesting (rclone-style drivers expose a Set/Supported list) and fall back to a supported type","Compute the hash client-side by streaming the file if the backend cannot provide it","Treat ErrUnsupported as 'hash unavailable', not as a hard failure — skip hash comparison for that transfer"],"exampleFix":"// before\nh, err := driver.Hash(hashType.MD5) // may return ErrUnsupported\nif err != nil { return err }\n\n// after\nh, err := driver.Hash(hashType.MD5)\nif errors.Is(err, utils.ErrUnsupported) {\n    h = computeLocalHash(reader, hashType.MD5) // client-side fallback\n}","handlingStrategy":"fallback","validationCode":"supported := driver.SupportedHashes() // rclone-style capability check\nif !sliceContains(supported, hashType.Name) {\n\t// pick a supported type or compute locally\n}","typeGuard":null,"tryCatchPattern":"h, err := driver.Hash(want)\nif errors.Is(err, utils.ErrUnsupported) {\n\th = computeLocally(reader, want)\n}","preventionTips":["Query driver capabilities before requesting hashes","Treat ErrUnsupported as 'unavailable', not fatal"],"tags":["hash","checksum","storage-driver","capability"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}