AlistGo/alist · warning · ErrUnsupported

hash type not supported

Error message

hash type not supported

What it means

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.

Source

Thrown at pkg/utils/hash.go:27

	"encoding/json"
	"errors"
	"hash"
	"io"
	"iter"

	"github.com/alist-org/alist/v3/internal/errs"
	log "github.com/sirupsen/logrus"
)

func GetMD5EncodeStr(data string) string {
	return HashData(MD5, []byte(data))
}

//inspired by "github.com/rclone/rclone/fs/hash"

// ErrUnsupported should be returned by filesystem,
// if it is requested to deliver an unsupported hash type.
var ErrUnsupported = errors.New("hash type not supported")

// HashType indicates a standard hashing algorithm
type HashType struct {
	Width   int
	Name    string
	Alias   string
	NewFunc func(...any) hash.Hash
}

func (ht *HashType) MarshalJSON() ([]byte, error) {
	return []byte(`"` + ht.Name + `"`), nil
}

func (ht *HashType) MarshalText() (text []byte, err error) {
	return []byte(ht.Name), nil
}

var (

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Query which hash types the driver supports before requesting (rclone-style drivers expose a Set/Supported list) and fall back to a supported type
  2. Compute the hash client-side by streaming the file if the backend cannot provide it
  3. Treat ErrUnsupported as 'hash unavailable', not as a hard failure — skip hash comparison for that transfer

Example fix

// before
h, err := driver.Hash(hashType.MD5) // may return ErrUnsupported
if err != nil { return err }

// after
h, err := driver.Hash(hashType.MD5)
if errors.Is(err, utils.ErrUnsupported) {
    h = computeLocalHash(reader, hashType.MD5) // client-side fallback
}
Defensive patterns

Strategy: fallback

Validate before calling

supported := driver.SupportedHashes() // rclone-style capability check
if !sliceContains(supported, hashType.Name) {
	// pick a supported type or compute locally
}

Try / catch

h, err := driver.Hash(want)
if errors.Is(err, utils.ErrUnsupported) {
	h = computeLocally(reader, want)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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