golang/go · error
ecdsa: invalid public key encoding
Error message
ecdsa: invalid public key encoding
What it means
Thrown by fips140/ecdsa.NewPublicKey when len(Q) < 1 or Q[0] == 0. An empty point or one beginning with 0x00 (the point-at-infinity / malformed) is rejected up front; SetBytes afterward validates on-curve membership and coordinate ranges per SP 800-89 §5.3.2.
Source
Thrown at src/crypto/internal/fips140/ecdsa/ecdsa.go:190
d, err := bigmod.NewNat().SetBytes(D, c.N)
if err != nil {
return nil, err
}
if d.IsZero() == 1 {
return nil, errors.New("ecdsa: private key is zero")
}
priv := &PrivateKey{pub: *pub, d: d.Bytes(c.N)}
return priv, nil
}
// NewPublicKey creates a new ECDSA public key from the given Q byte slice.
// Q must be the compressed or uncompressed encoding of the public point.
func NewPublicKey[P Point[P]](c *Curve[P], Q []byte) (*PublicKey, error) {
// SetBytes checks that Q is a valid point on the curve, and that its
// coordinates are reduced modulo p, fulfilling the requirements of SP
// 800-89, Section 5.3.2.
if len(Q) < 1 || Q[0] == 0 {
return nil, errors.New("ecdsa: invalid public key encoding")
}
_, err := c.newPoint().SetBytes(Q)
if err != nil {
return nil, err
}
return &PublicKey{curve: c.curve, q: Q}, nil
}
// GenerateKey generates a new ECDSA private key pair for the specified curve.
func GenerateKey[P Point[P]](c *Curve[P], rand io.Reader) (*PrivateKey, error) {
fips140.RecordApproved()
k, Q, err := randomPoint(c, func(b []byte) error {
return drbg.ReadWithReader(rand, b)
})
if err != nil {
return nil, err
}View on GitHub (pinned to b6b368adc5)
Solutions
- Validate len(Q) >= 1 and Q[0] != 0 before calling NewPublicKey.
- Re-serialize the point in SEC1 compressed (0x02/0x03) or uncompressed (0x04) form.
- Check the upstream parser that produced Q for truncation.
Example fix
// before
pub, err := ecdsa.NewPublicKey(curve, q) // q empty or q[0]==0x00
// after: guard the encoding
if len(q) == 0 || q[0] == 0 {
return errors.New("invalid public key encoding")
}
pub, err := ecdsa.NewPublicKey(curve, q) Defensive patterns
Strategy: validation
Validate before calling
if len(Q) < 1 || Q[0] == 0 {
return errors.New("ecdsa public key encoding is empty or starts with 0x00")
}
return ecdsa.NewPublicKey(curve, Q) Type guard
func validPubEnc(Q []byte) bool {
return len(Q) >= 1 && Q[0] != 0
} Prevention
- Re-serialize points in SEC1 form before importing.
- Check Q[0] is 0x02/0x03/0x04 at parse time.
- Validate certificate/JWK parsing did not truncate the point.
When it happens
Trigger: Constructing an ECDSA public key from an empty slice, a 0x00-prefixed buffer, or any encoding whose first byte is zero.
Common situations: Parsing a corrupted/truncated certificate or JWK, an uninitialized buffer, or a mis-serialized point that lost its format prefix.
Related errors
- ecdsa: invalid private key length
- crypto/ecdh: invalid public key
- ecdsa: private key is zero
- ecdsa: private key does not match curve
- ecdsa: private key scalar is zero or negative
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/484202b115cfca3f.
Report an issue: GitHub.