{"record":{"id":"e674f16425199343","repo":"golang/go","slug":"ecdsa-invalid-uncompressed-public-key","errorCode":null,"errorMessage":"ecdsa: invalid uncompressed public key","messagePattern":"ecdsa: invalid uncompressed public key","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/ecdsa/ecdsa.go","lineNumber":109,"sourceCode":"}\n\n// ParseUncompressedPublicKey parses a public key encoded as an uncompressed\n// point according to SEC 1, Version 2.0, Section 2.3.3 (also known as the X9.62\n// uncompressed format). It returns an error if the point is not in uncompressed\n// form, is not on the curve, or is the point at infinity.\n//\n// curve must be one of [elliptic.P224], [elliptic.P256], [elliptic.P384], or\n// [elliptic.P521], or ParseUncompressedPublicKey returns an error.\n//\n// ParseUncompressedPublicKey accepts the same format as\n// [ecdh.Curve.NewPublicKey] does for NIST curves, but returns a [PublicKey]\n// instead of an [ecdh.PublicKey].\n//\n// Note that public keys are more commonly encoded in DER (or PEM) format, which\n// can be parsed with [crypto/x509.ParsePKIXPublicKey] (and [encoding/pem]).\nfunc ParseUncompressedPublicKey(curve elliptic.Curve, data []byte) (*PublicKey, error) {\n\tif len(data) < 1 || data[0] != 4 {\n\t\treturn nil, errors.New(\"ecdsa: invalid uncompressed public key\")\n\t}\n\tswitch curve {\n\tcase elliptic.P224():\n\t\treturn parseUncompressedPublicKey(ecdsa.P224(), curve, data)\n\tcase elliptic.P256():\n\t\treturn parseUncompressedPublicKey(ecdsa.P256(), curve, data)\n\tcase elliptic.P384():\n\t\treturn parseUncompressedPublicKey(ecdsa.P384(), curve, data)\n\tcase elliptic.P521():\n\t\treturn parseUncompressedPublicKey(ecdsa.P521(), curve, data)\n\tdefault:\n\t\treturn nil, errors.New(\"ecdsa: curve not supported by ParseUncompressedPublicKey\")\n\t}\n}\n\nfunc parseUncompressedPublicKey[P ecdsa.Point[P]](c *ecdsa.Curve[P], curve elliptic.Curve, data []byte) (*PublicKey, error) {\n\tk, err := ecdsa.NewPublicKey(c, data)\n\tif err != nil {","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/ecdsa/ecdsa.go#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npub, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), derBytes)\n\n// after\n// for raw uncompressed point:\npub, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), rawPointBytes) // rawPointBytes[0] == 0x04\n// for DER/PEM:\n// block, _ := pem.Decode(pemBytes)\n// pubAny, err := x509.ParsePKIXPublicKey(block.Bytes)","handlingStrategy":"validation","validationCode":"func validateUncompressedPoint(data []byte, curve elliptic.Curve) error {\n    if len(data) < 1 || data[0] != 0x04 {\n        return errors.New(\"expected uncompressed point (prefix 0x04)\")\n    }\n    expectedLen := 1 + 2*((curve.Params().BitLen+7)/8)\n    if len(data) != expectedLen {\n        return fmt.Errorf(\"expected %d bytes, got %d\", expectedLen, len(data))\n    }\n    return nil\n}","typeGuard":"func isUncompressedPoint(data []byte) bool {\n    return len(data) >= 1 && data[0] == 0x04\n}","tryCatchPattern":"pub, err := ecdsa.ParseUncompressedPublicKey(curve, data)\nif err != nil {\n    return fmt.Errorf(\"not a valid uncompressed point (prefix=0x%02x): %w\", data[0], err)\n}","preventionTips":["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)."],"tags":["crypto","ecdsa","public-key","encoding","sec1","input-validation"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}