golang/go · error
ecdsa: invalid uncompressed public key
Error message
ecdsa: invalid uncompressed public key
What it means
Thrown by ecdsa.ParseUncompressedPublicKey when the input data is empty or its first byte is not 0x04. Per SEC 1 section 2.3.3, uncompressed elliptic curve points are encoded as 0x04 followed by the x and y coordinates. Any other prefix (0x02/0x03 for compressed, 0x00 for point at infinity) or missing data is rejected.
Source
Thrown at src/crypto/ecdsa/ecdsa.go:109
}
// ParseUncompressedPublicKey parses a public key encoded as an uncompressed
// point according to SEC 1, Version 2.0, Section 2.3.3 (also known as the X9.62
// uncompressed format). It returns an error if the point is not in uncompressed
// form, is not on the curve, or is the point at infinity.
//
// curve must be one of [elliptic.P224], [elliptic.P256], [elliptic.P384], or
// [elliptic.P521], or ParseUncompressedPublicKey returns an error.
//
// ParseUncompressedPublicKey accepts the same format as
// [ecdh.Curve.NewPublicKey] does for NIST curves, but returns a [PublicKey]
// instead of an [ecdh.PublicKey].
//
// Note that public keys are more commonly encoded in DER (or PEM) format, which
// can be parsed with [crypto/x509.ParsePKIXPublicKey] (and [encoding/pem]).
func ParseUncompressedPublicKey(curve elliptic.Curve, data []byte) (*PublicKey, error) {
if len(data) < 1 || data[0] != 4 {
return nil, errors.New("ecdsa: invalid uncompressed public key")
}
switch curve {
case elliptic.P224():
return parseUncompressedPublicKey(ecdsa.P224(), curve, data)
case elliptic.P256():
return parseUncompressedPublicKey(ecdsa.P256(), curve, data)
case elliptic.P384():
return parseUncompressedPublicKey(ecdsa.P384(), curve, data)
case elliptic.P521():
return parseUncompressedPublicKey(ecdsa.P521(), curve, data)
default:
return nil, errors.New("ecdsa: curve not supported by ParseUncompressedPublicKey")
}
}
func parseUncompressedPublicKey[P ecdsa.Point[P]](c *ecdsa.Curve[P], curve elliptic.Curve, data []byte) (*PublicKey, error) {
k, err := ecdsa.NewPublicKey(c, data)
if err != nil {View on GitHub (pinned to b6b368adc5)
Solutions
- Ensure data[0] == 0x04 and that the total length is 1 + 2*fieldSizeBytes (e.g., 65 bytes for P-256).
- If the key is DER/PEM encoded, use crypto/x509.ParsePKIXPublicKey instead of ParseUncompressedPublicKey.
- If the key is compressed (prefix 0x02/0x03), decompress it first or use a function that handles compressed points.
Example fix
// before pub, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), derBytes) // after // for raw uncompressed point: pub, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), rawPointBytes) // rawPointBytes[0] == 0x04 // for DER/PEM: // block, _ := pem.Decode(pemBytes) // pubAny, err := x509.ParsePKIXPublicKey(block.Bytes)
Defensive patterns
Strategy: validation
Validate before calling
func validateUncompressedPoint(data []byte, curve elliptic.Curve) error {
if len(data) < 1 || data[0] != 0x04 {
return errors.New("expected uncompressed point (prefix 0x04)")
}
expectedLen := 1 + 2*((curve.Params().BitLen+7)/8)
if len(data) != expectedLen {
return fmt.Errorf("expected %d bytes, got %d", expectedLen, len(data))
}
return nil
} Type guard
func isUncompressedPoint(data []byte) bool {
return len(data) >= 1 && data[0] == 0x04
} Try / catch
pub, err := ecdsa.ParseUncompressedPublicKey(curve, data)
if err != nil {
return fmt.Errorf("not a valid uncompressed point (prefix=0x%02x): %w", data[0], err)
} Prevention
- Use crypto/x509.ParsePKIXPublicKey for DER/PEM-encoded keys — ParseUncompressedPublicKey expects raw SEC 1 format only.
- Check data[0] == 0x04 before calling to distinguish from compressed points (0x02/0x03).
When it happens
Trigger: Calling ParseUncompressedPublicKey(curve, data) where data is empty, nil, or starts with a byte other than 0x04. Common cases: passing a compressed point (prefix 0x02 or 0x03), passing a DER/ASN.1 encoded SubjectPublicKeyInfo, or passing raw coordinate bytes without the 0x04 prefix.
Common situations: Receiving a compressed public key from a protocol that uses point compression and trying to parse it as uncompressed; loading a key from a DER-encoded certificate (which wraps the point in ASN.1 structures) without first using x509.ParsePKIXPublicKey; building the point bytes manually and forgetting the 0x04 header.
Related errors
- invalid ASN.1
- ecdsa: curve not supported by ParseUncompressedPublicKey
- ecdsa: curve not supported by PublicKey.Bytes
- ecdsa: curve not supported by ParseRawPrivateKey
- ecdsa: Sign must be called with a hash, not with crypto.Hash
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/e674f16425199343.
Report an issue: GitHub.