golang/go · error
ecdsa: curve not supported by PublicKey.Bytes
Error message
ecdsa: curve not supported by PublicKey.Bytes
What it means
Thrown by PublicKey.Bytes() when pub.Curve does not match any of P224, P256, P384, or P521 in the switch statement. The serialization to uncompressed SEC 1 format is only implemented for standard NIST curves via the internal FIPS ecdsa package.
Source
Thrown at src/crypto/ecdsa/ecdsa.go:155
// PublicKey.Curve must be one of [elliptic.P224], [elliptic.P256],
// [elliptic.P384], or [elliptic.P521], or Bytes returns an error.
//
// Bytes returns the same format as [ecdh.PublicKey.Bytes] does for NIST curves.
//
// Note that public keys are more commonly encoded in DER (or PEM) format, which
// can be generated with [crypto/x509.MarshalPKIXPublicKey] (and [encoding/pem]).
func (pub *PublicKey) Bytes() ([]byte, error) {
switch pub.Curve {
case elliptic.P224():
return publicKeyBytes(ecdsa.P224(), pub)
case elliptic.P256():
return publicKeyBytes(ecdsa.P256(), pub)
case elliptic.P384():
return publicKeyBytes(ecdsa.P384(), pub)
case elliptic.P521():
return publicKeyBytes(ecdsa.P521(), pub)
default:
return nil, errors.New("ecdsa: curve not supported by PublicKey.Bytes")
}
}
func publicKeyBytes[P ecdsa.Point[P]](c *ecdsa.Curve[P], pub *PublicKey) ([]byte, error) {
k, err := publicKeyToFIPS(c, pub)
if err != nil {
return nil, err
}
return k.Bytes(), nil
}
// PrivateKey represents an ECDSA private key.
type PrivateKey struct {
PublicKey
// D is the private scalar value.
//
// Deprecated: modifying the raw value can produce invalid keys, and mayView on GitHub (pinned to b6b368adc5)
Solutions
- Ensure the PublicKey was created with a standard NIST curve (P224/P256/P384/P521) — validate at construction time.
- If using a custom curve, implement your own serialization using the X and Y big.Int fields directly.
- Check pub.Curve against the standard singletons before calling Bytes() and handle the unsupported case explicitly.
Example fix
// before
b, err := pub.Bytes()
// after
switch pub.Curve {
case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521():
b, err = pub.Bytes()
default:
// manual serialization for non-NIST curves
b = append([]byte{0x04}, append(pub.X.FillBytes(make([]byte, pub.Curve.Params().BitSize/8)), pub.Y.FillBytes(make([]byte, pub.Curve.Params().BitSize/8))...)
} Defensive patterns
Strategy: validation
Validate before calling
func canSerializePublicKey(pub *ecdsa.PublicKey) bool {
switch pub.Curve {
case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521():
return true
}
return false
} Try / catch
b, err := pub.Bytes()
if err != nil {
// fall back to manual serialization using pub.X, pub.Y
fieldSize := (pub.Curve.Params().BitLen + 7) / 8
b = append([]byte{0x04}, append(pub.X.FillBytes(make([]byte, fieldSize)), pub.Y.FillBytes(make([]byte, fieldSize))...)...)
} Prevention
- Always construct PublicKeys using GenerateKey or parsing functions that enforce standard curves.
- For non-NIST curves, serialize X and Y coordinates manually.
When it happens
Trigger: Calling Bytes() on a PublicKey where Curve is a custom or non-standard elliptic.Curve. This can also occur if the curve was set to the Params() value or a third-party curve type that doesn't match the singletons.
Common situations: Loading keys from external sources that specify non-standard curves; programmatically constructing a PublicKey with a custom curve; deserialization code that doesn't validate the curve before calling Bytes().
Related errors
- ecdsa: curve not supported by PrivateKey.Bytes
- ecdsa: unsupported curve by crypto/ecdh
- ecdsa: invalid uncompressed public key
- ecdsa: curve not supported by ParseUncompressedPublicKey
- ecdsa: curve not supported by ParseRawPrivateKey
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/29e39a5d5c96bf5e.
Report an issue: GitHub.