Error message
x509: unsupported elliptic curve
Go crypto/x509 — ParsePKIXPublicKey / ParseCertificate / ParseECPrivateKey
What it means
The key or certificate parses structurally, but its curve OID is not one Go's standard library supports: crypto/x509 handles the NIST curves P-224, P-256, P-384 and P-521 only. In practice this error almost always means one specific curve — secp256k1, the Bitcoin/Ethereum curve, which is deliberately outside the stdlib: the Go team ships the NIST curves with constant-time implementations and leaves everything else to third-party packages.
Why it happens
secp256k1 key material in stdlib parsers
commonKeys generated with openssl ecparam -name secp256k1 (or exported from blockchain tooling) carry OID 1.3.132.0.10. Go's x509 package recognizes the OID as an EC key but has no curve implementation for it and stops here.
Brainpool, GOST or other national curves
occasionalEuropean Brainpool certificates and other non-NIST curves appear in some government and banking ecosystems; the stdlib treats them exactly like secp256k1 — parseable envelope, unsupported curve.
Legacy small curves
rareOld material on secp160/192-class curves is both unsupported and cryptographically inadequate today; migration, not parsing, is the answer.
How to fix it
- 1.
Parse secp256k1 with a dedicated library
Extract the raw point yourself (or from the SEC1 structure) and hand it to a maintained secp256k1 implementation such as dcrd's.
go import ( "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" ) pub, err := secp256k1.ParsePubKey(pointBytes) // 33/65-byte SEC1 point ok := ecdsa.VerifySignature(...) // via the package's ecdsa subpackage - 2.
Or move the workload to P-256
If nothing in the system requires secp256k1 (no blockchain interop), regenerate on a stdlib-supported curve and the whole toolchain simplifies.
bash openssl ecparam -name prime256v1 -genkey -noout -out key.pem openssl pkey -in key.pem -pubout -out pub.pem - 3.
Confirm which curve the material actually uses
Before reaching for a library, read the curve OID out of the file: 1.3.132.0.10 is secp256k1, 1.2.840.10045.3.1.7 is P-256. This also catches mislabeled files where the curve is not what the filename or the documentation claims.
bash openssl ec -in key.pem -noout -text | grep -A1 "ASN1 OID" openssl x509 -in cert.pem -noout -text | grep -iA2 "public key algorithm"