kubernetes/kops · error

unknown hash algorithm: %q

Error message

unknown hash algorithm: %q

What it means

HashAlgorithm.FromString in util/pkg/hashing parses a hex-encoded hash string into a Hash for the given algorithm. The method only knows md5 (32 hex chars), sha1 (40) and sha256 (64); if the HashAlgorithm receiver holds any other value, there is no expected length and it returns this error. It guards against typos or uninitialized algorithm fields in asset/hash configuration.

Source

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

	case HashAlgorithmSHA256:
		return sha256.New()
	}

	klog.Exitf("Unknown hash algorithm: %v", ha)
	return nil
}

func (ha HashAlgorithm) FromString(s string) (*Hash, error) {
	var l int
	switch ha {
	case HashAlgorithmMD5:
		l = 32
	case HashAlgorithmSHA1:
		l = 40
	case HashAlgorithmSHA256:
		l = 64
	default:
		return nil, fmt.Errorf("unknown hash algorithm: %q", ha)
	}

	if len(s) != l {
		return nil, fmt.Errorf("invalid %q hash - unexpected length %d", ha, len(s))
	}

	hashValue, err := hex.DecodeString(s)
	if err != nil {
		return nil, fmt.Errorf("invalid hash %q - not hex", s)
	}
	return &Hash{Algorithm: ha, HashValue: hashValue}, nil
}

func MustFromString(s string) *Hash {
	h, err := FromString(s)
	if err != nil {
		klog.Fatalf("FromString(%q) failed with %v", s, err)
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use the exported constants hashing.HashAlgorithmMD5, HashAlgorithmSHA1, or HashAlgorithmSHA256 instead of string literals
  2. If parsing "algo:hex" strings, normalize the prefix and map it explicitly to a supported constant before calling FromString
  3. Fix the casing/spelling: the algorithm must be exactly "md5", "sha1", or "sha256" (lowercase)
  4. Prefer sha256 for new assets — md5/sha1 exist for legacy compatibility only

Example fix

// before
algo := hashing.HashAlgorithm(strings.Split(s, ":")[0]) // "SHA256" from config
h, err := algo.FromString(hex)
// after
var algo hashing.HashAlgorithm
switch strings.ToLower(strings.Split(s, ":")[0]) {
case "md5": algo = hashing.HashAlgorithmMD5
case "sha1": algo = hashing.HashAlgorithmSHA1
case "sha256": algo = hashing.HashAlgorithmSHA256
default: return fmt.Errorf("unsupported hash algorithm in config")
}
h, err := algo.FromString(hex)
Defensive patterns

Strategy: validation

Validate before calling

func validHashAlgo(a hashing.HashAlgorithm) bool {
    switch a {
    case hashing.HashAlgorithmMD5, hashing.HashAlgorithmSHA1, hashing.HashAlgorithmSHA256:
        return true
    }
    return false
}
// call before FromString:
if !validHashAlgo(algo) {
    return fmt.Errorf("config: algorithm %q must be md5, sha1, or sha256", algo)
}

Type guard

func isKnownHashAlgorithm(a hashing.HashAlgorithm) bool {
    return a == hashing.HashAlgorithmMD5 ||
        a == hashing.HashAlgorithmSHA1 ||
        a == hashing.HashAlgorithmSHA256
}

Try / catch

h, err := algo.FromString(hexHash)
if err != nil {
    if strings.Contains(err.Error(), "unknown hash algorithm") {
        return fmt.Errorf("bad hash algorithm %q in config (want md5|sha1|sha256): %w", algo, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling FromString (directly or via GetHash/findHash/buildFileAsset/Add) with a HashAlgorithm value outside {"md5","sha1","sha256"} — e.g. hashing.HashAlgorithm("sha512"), hashing.HashAlgorithm(""), a misspelled "sha-256", or a value deserialized from user config (kops cluster spec hash fields) without validation.

Common situations: Typo in a cluster spec or asset config writing "SHA256"/"sha-256" instead of "sha256" (the constants are lowercase, case-sensitive); code defaulting to sha512 because it sounded stronger; an empty algorithm string from partially parsed "sha256:abcdef"-style strings where the prefix split failed; tests constructing HashAlgorithm from raw YAML/JSON input.

Related errors


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