golang/go · error
ecdsa: Sign called with nil random and nil opts
Error message
ecdsa: Sign called with nil random and nil opts
What it means
Thrown by signRFC6979 when opts is nil. This path is reached from PrivateKey.Sign when the random parameter is nil (requesting deterministic RFC 6979 signing). Deterministic signing requires knowing which hash function produced the digest, which comes from opts.HashFunc(). With nil opts, the hash function is undefined, so signing cannot proceed.
Source
Thrown at src/crypto/ecdsa/ecdsa.go:441
return nil, errors.New("crypto/ecdsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
}
k, err := privateKeyToFIPS(c, priv)
if err != nil {
return nil, err
}
// Always using SHA-512 instead of the hash that computed hash is
// technically a violation of draft-irtf-cfrg-det-sigs-with-noise-04 but in
// our API we don't get to know what it was, and this has no security impact.
sig, err := ecdsa.Sign(c, sha512.New, k, rand, hash)
if err != nil {
return nil, err
}
return encodeSignature(sig.R, sig.S)
}
func signRFC6979(priv *PrivateKey, hash []byte, opts crypto.SignerOpts) ([]byte, error) {
if opts == nil {
return nil, errors.New("ecdsa: Sign called with nil random and nil opts")
}
h := opts.HashFunc()
switch priv.Curve.Params() {
case elliptic.P224().Params():
return signFIPSDeterministic(ecdsa.P224(), h, priv, hash)
case elliptic.P256().Params():
return signFIPSDeterministic(ecdsa.P256(), h, priv, hash)
case elliptic.P384().Params():
return signFIPSDeterministic(ecdsa.P384(), h, priv, hash)
case elliptic.P521().Params():
return signFIPSDeterministic(ecdsa.P521(), h, priv, hash)
default:
return nil, errors.New("ecdsa: curve not supported by deterministic signatures")
}
}
func signFIPSDeterministic[P ecdsa.Point[P]](c *ecdsa.Curve[P], hashFunc crypto.Hash, priv *PrivateKey, hash []byte) ([]byte, error) {
k, err := privateKeyToFIPS(c, priv)View on GitHub (pinned to b6b368adc5)
Solutions
- When requesting deterministic signing (random=nil), always provide a non-nil crypto.SignerOpts: priv.Sign(nil, digest, crypto.SHA256).
- If you want randomized signing, pass a non-nil random reader (e.g., rand.Reader) — then nil opts is acceptable.
- Understand the API contract: nil random = deterministic (requires opts), non-nil random = randomized (opts optional).
Example fix
// before sig, err := priv.Sign(nil, digest, nil) // both nil — error // after sig, err := priv.Sign(nil, digest, crypto.SHA256) // deterministic with SHA-256
Defensive patterns
Strategy: validation
Validate before calling
func validateSignParams(random io.Reader, opts crypto.SignerOpts) error {
if random == nil && opts == nil {
return errors.New("deterministic signing requires non-nil opts with a hash")
}
return nil
} Type guard
func canSignDeterministically(opts crypto.SignerOpts) bool {
return opts != nil && opts.HashFunc() != 0
} Try / catch
sig, err := priv.Sign(random, digest, opts)
if err != nil && strings.Contains(err.Error(), "nil random and nil opts") {
// provide opts to enable deterministic signing
sig, err = priv.Sign(nil, digest, crypto.SHA256)
} Prevention
- When random is nil (deterministic), always provide opts with a real hash function.
- Pass crypto.Hash values directly as opts since crypto.Hash implements SignerOpts.
When it happens
Trigger: Calling priv.Sign(nil, digest, nil) — nil random triggers the deterministic RFC 6979 path, and nil opts means no hash function is specified. The Sign method only validates opts when it's non-nil, so nil opts passes through to signRFC6979 which then rejects it.
Common situations: Code that passes nil for both random and opts expecting some default behavior; misunderstanding the API where nil random means deterministic but forgetting that opts is still required to specify the hash; refactoring that accidentally nullifies opts.
Related errors
- ecdsa: Sign must be called with a hash, not with crypto.Hash
- ecdsa: curve not supported by deterministic signatures
- ecdsa: requested hash function unavailable:
- crypto/ecdsa: use of hash functions other than SHA-2 or SHA-
- ecdsa: hash length does not match hash function
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/864d9da03faabee3.
Report an issue: GitHub.