hashicorp/terraform · error · ErrInvalidSHA256Hash

the value was not a valid SHA-256 hash

Error message

the value was not a valid SHA-256 hash

What it means

ErrInvalidSHA256Hash is returned by SHA256FromHex when the input string is not a valid 64-character hex-encoded SHA-256 digest — either hex.DecodeString fails (non-hex characters / odd length) or the decoded byte length is not sha256.Size (32 bytes). It is also surfaced (wrapped) by ParseChecksums when a line of a SHA256SUMS file is malformed.

Source

Thrown at internal/releaseauth/hash.go:19

// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1

package releaseauth

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"fmt"
	"log"
)

// SHA256Hash represents a 256-bit SHA hash
type SHA256Hash [sha256.Size]byte

// ErrInvalidSHA256Hash is returned when the hash is invalid
var ErrInvalidSHA256Hash = errors.New("the value was not a valid SHA-256 hash")

// SHA256FromHex decodes a SHA256Hash from a hex string dump
func SHA256FromHex(hashHex string) (SHA256Hash, error) {
	var result [sha256.Size]byte
	hash, err := hex.DecodeString(hashHex)
	if err != nil || len(hash) != sha256.Size {
		return result, ErrInvalidSHA256Hash
	}

	if copy(result[:], hash) != sha256.Size {
		panic("could not copy hash value")
	}

	return result, nil
}

// SHA256Checksums decodes a file generated by the sha256sum program
type SHA256Checksums map[string]SHA256Hash

View on GitHub (pinned to d32a084675)

Solutions

  1. Provide exactly 64 lowercase hex characters (sha256.Size*2) with no leading/trailing whitespace.
  2. Trim any whitespace/newlines from the hex string before calling SHA256FromHex.
  3. If parsing SHA256SUMS, ensure the file uses the standard '<64-hex> <filename>' two-space format.
  4. Cross-check the digest length: len(hashHex) must equal 64.

Example fix

// before
h, err := releaseauth.SHA256FromHex("abc123")

// after
h, err := releaseauth.SHA256FromHex(strings.TrimSpace(rawDigest))
if err != nil {
    return fmt.Errorf("invalid sha256 in config (need 64 hex chars): %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate length and charset
raw := strings.TrimSpace(rawDigest)
if len(raw) != 64 || !regexp.MustCompile(`^[0-9a-fA-F]{64}$`).MatchString(raw) {
    return fmt.Errorf("digest must be 64 hex chars")
}

Type guard

func isValidSHA256Hex(s string) bool {
    s = strings.TrimSpace(s)
    return len(s) == 64 && regexp.MustCompile(`^[0-9a-fA-F]{64}$`).MatchString(s)
}

Try / catch

h, err := releaseauth.SHA256FromHex(strings.TrimSpace(raw))
if errors.Is(err, releaseauth.ErrInvalidSHA256Hash) {
    return fmt.Errorf("config has an invalid sha256 (need 64 hex chars): %w", err)
}

Prevention

When it happens

Trigger: Calling SHA256FromHex with a string that is the wrong length (not 64 hex chars), contains whitespace/non-hex characters, or is a different hash algorithm's digest. ParseChecksums hits this when a SHA256SUMS line's first field is malformed.

Common situations: Hardcoded/pasted checksum with a stray space or newline; a SHA-1/MD5 digest passed instead of SHA-256; truncated digest; copy-paste from a checksum listing that uses a different format.

Related errors


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