golang/go · error
ecdsa: hash cannot be empty
Error message
ecdsa: hash cannot be empty
What it means
Thrown by SignASN1 when the hash parameter is empty (len(hash) == 0). ECDSA signing requires a non-empty hash digest — an empty hash indicates the caller didn't hash the message at all. This is a guard against trivially insecure signatures on empty data and prevents ambiguous signing behavior.
Source
Thrown at src/crypto/ecdsa/ecdsa.go:393
privateKey, err := ecdsa.GenerateKey(c, rand)
if err != nil {
return nil, err
}
return privateKeyFromFIPS(curve, privateKey)
}
// SignASN1 signs a hash (which should be the result of hashing a larger message)
// using the private key, priv. If the hash is longer than the bit-length of the
// private key's curve order, the hash will be truncated to that length. It
// returns the ASN.1 encoded signature.
//
// The signature is randomized. Since Go 1.26, a secure source of random bytes
// is always used, and the Reader is ignored unless GODEBUG=cryptocustomrand=1
// is set. This setting will be removed in a future Go release. Instead, use
// [testing/cryptotest.SetGlobalRandom].
func SignASN1(r io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
if len(hash) == 0 {
return nil, errors.New("ecdsa: hash cannot be empty")
}
if boring.Enabled && rand.IsDefaultReader(r) {
b, err := boringPrivateKey(priv)
if err != nil {
return nil, err
}
return boring.SignMarshalECDSA(b, hash)
}
boring.UnreachableExceptTests()
r = rand.CustomReader(r)
switch priv.Curve.Params() {
case elliptic.P224().Params():
return signFIPS(ecdsa.P224(), priv, r, hash)
case elliptic.P256().Params():
return signFIPS(ecdsa.P256(), priv, r, hash)View on GitHub (pinned to b6b368adc5)
Solutions
- Always hash the message before calling SignASN1: digest := sha256.Sum256(msg); then pass digest[:].
- Add a pre-check: if len(hash) == 0 { return error } before calling SignASN1 to give a more descriptive error.
- Verify the hashing pipeline produces non-empty output for all expected inputs.
Example fix
// before sig, err := ecdsa.SignASN1(rand.Reader, priv, nil) // after digest := sha256.Sum256(msg) sig, err := ecdsa.SignASN1(rand.Reader, priv, digest[:])
Defensive patterns
Strategy: validation
Validate before calling
func validateHashNotEmpty(hash []byte) error {
if len(hash) == 0 {
return errors.New("hash digest must not be empty")
}
return nil
} Type guard
func isNonEmptyHash(hash []byte) bool {
return len(hash) > 0
} Try / catch
sig, err := ecdsa.SignASN1(r, priv, hash)
if err != nil {
return fmt.Errorf("cannot sign empty hash (len=%d): %w", len(hash), err)
} Prevention
- Always hash the message before signing — never pass raw or empty data to SignASN1.
- Add a guard: if len(digest) == 0 { return err } before calling SignASN1.
When it happens
Trigger: Calling ecdsa.SignASN1(r, priv, hash) where hash is nil or an empty byte slice. This occurs when the caller forgets to hash the message, passes an uninitialized hash variable, or accidentally passes an empty message through a hash function that produced no output (shouldn't happen with standard hashes but can with custom pipelines).
Common situations: Code that signs a potentially-empty message without checking; deserialization bugs that produce empty digests; forgetting to call the hash function and passing the message directly (if the message itself is empty); refactoring that accidentally removes the hashing step.
Related errors
- ecdsa: Sign must be called with a hash, not with crypto.Hash
- ecdsa: hash length does not match hash function
- ecdsa: requested hash function unavailable:
- crypto/ecdsa: use of hash functions other than SHA-2 or SHA-
- ecdsa: hash cannot be empty
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/1add0af1e828a570.
Report an issue: GitHub.