eclipse-vertx/vert.x · error · VertxException

Invalid DER: not a sequence

Error message

Invalid DER: not a sequence

What it means

Thrown by getECKeySpec when the first DER object of the supplied key bytes is not an ASN.1 SEQUENCE. An RFC 5915 ECPrivateKey is a SEQUENCE at top level, so anything else means the bytes are not a DER EC private key. Usually the input is a malformed, truncated, or wrongly-formatted key blob.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/net/impl/pkcs1/PrivateKeyParser.java:154

   * contain the Base64 encoded DER-encoding of an ECPrivateKey sandwiched between
   * <pre>
   * -----BEGIN EC PRIVATE KEY-----
   * -----END EC PRIVATE KEY-----
   * </pre>
   * as described in <a href="https://datatracker.ietf.org/doc/html/rfc5915#section-4">
   * RFC 5915, Section 4</a>
   *
   * @see "https://datatracker.ietf.org/doc/html/rfc5915"
   * @param keyBytes The encoded key.
   * @return The spec that can be used to instantiate the private key.
   * @throws VertxException if the byte array does not represent an ASN.1 ECPrivateKey structure.
   */
  public static ECPrivateKeySpec getECKeySpec(byte[] keyBytes) throws VertxException {
    DerParser parser = new DerParser(keyBytes);

    Asn1Object sequence = parser.read();
    if (sequence.getType() != DerParser.SEQUENCE) {
      throw new VertxException("Invalid DER: not a sequence");
    }

    // Parse inside the sequence
    parser = sequence.getParser();

    Asn1Object version = parser.read();
    if (version.getType() != DerParser.INTEGER) {
      throw new VertxException(String.format(
          "Invalid DER: 'version' field must be of type INTEGER (2) but found type `%d`",
          version.getType()));
    } else if (version.getInteger().intValue() != 1) {
      throw new VertxException(String.format(
          "Invalid DER: expected 'version' field to have value '1' but found '%d'",
          version.getInteger().intValue()));
    }
    byte[] privateValue = parser.read().getValue();
    parser = parser.read().getParser();
    Asn1Object params = parser.read();

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Ensure the input is a DER-encoded ECPrivateKey (SEC1/RFC 5915), not PKCS#8; unwrap PKCS#8 first if needed.
  2. Regenerate or re-export the key: openssl ec -in key.pem -outform DER -out key.der.
  3. Validate the DER with openssl asn1parse -inform DER -in key.der before loading.
  4. Check the code path does not pass a certificate or public key where the private key is expected.

Example fix

// before
byte[] bytes = pkcs8PemBody.getBytes(); // PKCS#8 wrapper, wrong format
ECPrivateKeySpec spec = PrivateKeyParser.getECKeySpec(bytes);
// after
PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(pkcs8PemBody.getBytes());
PrivateKey key = KeyFactory.getInstance("EC").generatePrivate(pkcs8);
Defensive patterns

Strategy: validation

Validate before calling

byte[] der = Base64.getMimeDecoder().decode(pemBody);
// first byte must be 0x30 (SEQUENCE)
if (der.length < 2 || der[0] != 0x30) {
    throw new IllegalArgumentException("Not a DER SEQUENCE: expected 0x30 tag, got " + (der.length > 0 ? der[0] : "EOF"));
}

Try / catch

try {
    return PrivateKeyParser.getECKeySpec(der);
} catch (VertxException e) {
    throw new IllegalArgumentException("Invalid EC private key DER: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Calling PrivateKeyParser.getECKeySpec with bytes that begin with a non-SEQUENCE ASN.1 tag, e.g. passing a raw SEC1/PKCS#1 body instead of the ECPrivateKey structure, or a corrupted/truncated DER buffer.

Common situations: Hand-deriving key bytes from a PEM file and slicing off the header incorrectly; feeding a PKCS#8-wrapped key into the SEC1 parser; copy/paste corruption of base64 key material.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/63531fe43c9ad792. Report an issue: GitHub.