kubernetes/kops · error

cannot determine algorithm for hash length: %d

Error message

cannot determine algorithm for hash length: %d

What it means

The bare-string FromString infers the hash algorithm purely from string length: 32=MD5, 40=SHA1, 64=SHA256. This error is thrown when the string's length matches none of those sizes. It is a guard against feeding arbitrary or corrupted strings into hash-based lookups.

Source

Thrown at util/pkg/hashing/hash.go:122

func FromString(s string) (*Hash, error) {
	for _, ha := range []HashAlgorithm{HashAlgorithmMD5, HashAlgorithmSHA1, HashAlgorithmSHA256} {
		prefix := fmt.Sprintf("%s:", ha)
		if strings.HasPrefix(s, prefix) {
			return ha.FromString(s[len(prefix):])
		}
	}

	var ha HashAlgorithm
	switch len(s) {
	case 32:
		ha = HashAlgorithmMD5
	case 40:
		ha = HashAlgorithmSHA1
	case 64:
		ha = HashAlgorithmSHA256
	default:
		return nil, fmt.Errorf("cannot determine algorithm for hash length: %d", len(s))
	}

	return ha.FromString(s)
}

func (ha HashAlgorithm) Hash(r io.Reader) (*Hash, error) {
	hasher := ha.NewHasher()
	_, err := copyToHasher(hasher, r)
	if err != nil {
		return nil, fmt.Errorf("error while hashing resource: %v", err)
	}
	return &Hash{Algorithm: ha, HashValue: hasher.Sum(nil)}, nil
}

func (ha HashAlgorithm) HashFile(p string) (*Hash, error) {
	f, err := os.OpenFile(p, os.O_RDONLY, 0)
	if err != nil {
		if os.IsNotExist(err) {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure the hash string is exactly 32, 40, or 64 characters long
  2. Trim whitespace/newlines and remove any algorithm prefix before calling FromString
  3. If using SHA-512 or another size, call the explicit HashAlgorithm's FromString after extending the switch, rather than the length-inferring variant

Example fix

// before
h, err := hashing.FromString(hashWithPrefix) // "sha256:abc..." -> wrong length
// after
h, err := hashing.HashAlgorithmSHA256.FromString(strings.TrimPrefix(hashWithPrefix, "sha256:"))
Defensive patterns

Strategy: validation

Validate before calling

func hashable(s string) bool {
	s = strings.TrimSpace(s)
	switch len(s) { case 32, 40, 64: return isHex(s) }
	return false
}
if !hashable(s) { return fmt.Errorf("hash must be 32, 40 or 64 hex chars, got %d", len(strings.TrimSpace(s))) }

Type guard

func isKnownHashLength(s string) bool {
	switch len(strings.TrimSpace(s)) {
	case 32, 40, 64:
		return true
	}
	return false
}

Try / catch

h, err := hashing.FromString(strings.TrimSpace(raw))
if err != nil {
	if strings.Contains(err.Error(), "cannot determine algorithm") {
		return fmt.Errorf("input %q (len %d) is not an md5/sha1/sha256 digest", raw, len(raw))
	}
	return err
}

Prevention

When it happens

Trigger: Calling hashing.FromString("...") (the length-inference entry point) with a string of length 0, 33, 56, or 128 — e.g. an empty hash variable, a SHA-512 value, or a URL accidentally passed instead of a checksum.

Common situations: Asset/PKI lookups where the hash field was never populated (empty string); switching to SHA-512 in custom tooling; concatenating algorithm name and hash so length is off; reading a hash file that includes a trailing newline handled elsewhere.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/d953e33935601d78. Report an issue: GitHub.