hashicorp/terraform · error

checksum list has invalid SHA256 hash

Error message

checksum list has invalid SHA256 hash %q: %s

What it means

Thrown by matchingChecksumAuthentication.AuthenticatePackage when a matching filename line is found but its hash field cannot be hex-decoded into a 32-byte SHA-256. The matched line's first field (checksum) is passed to hex.Decode into gotSHA256Sum; any decode error (non-hex characters, wrong length) is wrapped at package_authentication.go:365-367.

Solutions

  1. Regenerate the SHA256SUMS document so each hash is exactly 64 lowercase hex characters.
  2. Validate the sums document format server-side: each line is '<64-hex> <filename>'.
  3. Confirm the registry/mirror computes SHA-256 (not MD5/SHA-1/SHA-512) and emits it in hex.
  4. If a proxy rewrites responses, fetch the sums document directly to compare against the origin.
Defensive patterns

Strategy: validation

Validate before calling

// Validate each hash field in the sums document is 64 lowercase hex chars.
func validateSumsFormat(document []byte) error {
    for i, line := range bytes.Split(document, []byte("\n")) {
        parts := bytes.Fields(line)
        if len(parts) < 2 { // skip blank/short lines
            continue
        }
        if len(parts[0]) != 64 {
            return fmt.Errorf("line %d: hash %q is not 64 hex chars", i, string(parts[0]))
        }
        if _, err := hex.Decode(make([]byte, 32), parts[0]); err != nil {
            return fmt.Errorf("line %d: invalid hex hash %q: %w", i, string(parts[0]), err)
        }
    }
    return nil
}

Prevention

When it happens

Trigger: The SHA256SUMS document has a line for m.Filename whose hash field is malformed: not 64 hex chars, contains whitespace/non-hex, or is truncated. A custom registry/mirror emitting a bad sums line, or a document that was edited/corrupted in transit.

Common situations: Custom mirror generating sums with a wrong algorithm prefix or uppercase that survived byte-splitting but fails hex.Decode; a sums document corrupted by a proxy/CDN; an MD5 or SHA-1 hash mistakenly placed where a SHA-256 hex string should be (too short).

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/3cb0c8bd18012840. Report an issue: GitHub.

Appendix: source

Thrown at internal/getproviders/package_authentication.go:367

	// Find the checksum in the list with matching filename. The document is
	// in the form "0123456789abcdef filename.zip".
	filename := []byte(m.Filename)
	var checksum []byte
	for _, line := range bytes.Split(m.Document, []byte("\n")) {
		parts := bytes.Fields(line)
		if len(parts) > 1 && bytes.Equal(parts[1], filename) {
			checksum = parts[0]
			break
		}
	}
	if checksum == nil {
		return nil, fmt.Errorf("checksum list has no SHA-256 hash for %q", m.Filename)
	}

	// Decode the ASCII checksum into a byte array for comparison.
	var gotSHA256Sum [sha256.Size]byte
	if _, err := hex.Decode(gotSHA256Sum[:], checksum); err != nil {
		return nil, fmt.Errorf("checksum list has invalid SHA256 hash %q: %s", string(checksum), err)
	}

	// If the checksums don't match, authentication fails.
	if !bytes.Equal(gotSHA256Sum[:], m.WantSHA256Sum[:]) {
		return nil, fmt.Errorf("checksum list has unexpected SHA-256 hash %x (expected %x)", gotSHA256Sum, m.WantSHA256Sum[:])
	}

	// Success! But this doesn't result in any real authentication, only a
	// lack of authentication errors, so we return a nil result.
	return nil, nil
}

type signatureAuthentication struct {
	Document  []byte
	Signature []byte
	Keys      []SigningKey
}

View on GitHub (pinned to d32a084675)