golang/go · error

ecdsa: curve not supported by ParseUncompressedPublicKey

Error message

ecdsa: curve not supported by ParseUncompressedPublicKey

What it means

Thrown by ParseUncompressedPublicKey when the provided curve does not match any of the four supported NIST curves: elliptic.P224, P256, P384, or P521. The switch statement has no case for custom or non-NIST curves, so the default branch fires.

Source

Thrown at src/crypto/ecdsa/ecdsa.go:121

// 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 {
		return nil, err
	}
	return publicKeyFromFIPS(curve, k)
}

// Bytes encodes the public key 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 public key is invalid.
//
// PublicKey.Curve must be one of [elliptic.P224], [elliptic.P256],
// [elliptic.P384], or [elliptic.P521], or Bytes returns an error.
//

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use the canonical curve singletons: elliptic.P224(), elliptic.P256(), elliptic.P384(), or elliptic.P521() — not their .Params() counterparts.
  2. If using a non-NIST curve, implement your own point parsing logic rather than relying on ParseUncompressedPublicKey.
  3. Verify the curve identity with a type assertion or comparison to the known singletons before calling this function.

Example fix

// before
pub, err := ecdsa.ParseUncompressedPublicKey(curve.Params(), data)

// after
pub, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), data) // pass the singleton, not .Params()
Defensive patterns

Strategy: validation

Validate before calling

func isSupportedNISTCurve(c elliptic.Curve) bool {
    switch c {
    case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521():
        return true
    }
    return false
}

Try / catch

pub, err := ecdsa.ParseUncompressedPublicKey(curve, data)
if err != nil {
    return fmt.Errorf("curve %s not supported: %w", curve.Params().Name, err)
}

Prevention

When it happens

Trigger: Calling ParseUncompressedPublicKey with a custom elliptic.Curve implementation, a curve from a third-party library, or any curve not returned by elliptic.P224()/P256()/P384()/P521(). Note that even elliptic.P521() is supported but using curve.Params() instead of the singleton may fail because the switch compares interface values.

Common situations: Using a non-standard curve for specialized applications; passing elliptic.P256().Params() instead of elliptic.P256() (the switch compares the concrete curve object); third-party curve implementations that wrap or extend the standard curves.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/9ac846a1d626b9ca. Report an issue: GitHub.