eclipse-vertx/vert.x · error · VertxException

Invalid DER: 'version' field must be of type INTEGER (2) but

Error message

Invalid DER: 'version' field must be of type INTEGER (2) but found type `%d`

What it means

Thrown by getECKeySpec when the 'version' field inside the ECPrivateKey SEQUENCE is not an ASN.1 INTEGER. RFC 5915 requires the first field of an ECPrivateKey to be INTEGER version 1. This indicates the DER structure does not match the expected EC private key layout.

Source

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

   * @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();
    // ECParameters are mandatory according to RFC 5915, Section 3
    if (params.getType() != DerParser.OBJECT_IDENTIFIER) {
      throw new VertxException(String.format(
          "Invalid DER: expected to find an OBJECT_IDENTIFIER (6) in 'parameters' but found type '%d'",
          params.getType()));
    }
    byte[] namedCurveOid = params.getValue();
    ECParameterSpec spec = getECParameterSpec(oidToString(namedCurveOid));

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Convert the key to SEC1 form: openssl ec -in key.pem -outform DER.
  2. If the key is PKCS#8, use KeyFactory EC/PKCS8EncodedKeySpec instead of this parser.
  3. Re-export the EC key from the source ensuring RFC 5915 layout.
  4. Validate structure with openssl asn1parse to confirm the version field is INTEGER 1.

Example fix

// before
ECPrivateKeySpec spec = PrivateKeyParser.getECKeySpec(pkcs8Bytes);
// after
openssl ec -in key.pkcs8.pem -outform DER -out key.sec1.der
ECPrivateKeySpec spec = PrivateKeyParser.getECKeySpec(Files.readAllBytes(Path.of("key.sec1.der")));
Defensive patterns

Strategy: validation

Validate before calling

// Ensure input is SEC1 ECPrivateKey, not PKCS#8 (PKCS#8 has a second SEQUENCE after version)
byte[] der = Base64.getMimeDecoder().decode(pemBody);
boolean looksLikePkcs8 = der.length > 4 && der[0] == 0x30 && der[1] > 40; // heuristic; verify with openssl asn1parse
if (pemHeader.contains("PRIVATE KEY") && !pemHeader.contains("EC PRIVATE KEY")) {
    throw new IllegalArgumentException("Use SEC1 'EC PRIVATE KEY' PEM for getECKeySpec");
}

Try / catch

try {
    return PrivateKeyParser.getECKeySpec(der);
} catch (VertxException e) {
    if (e.getMessage().contains("version")) {
        throw new KeyFormatException("Wrong key encoding for EC parser: " + e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing a DER structure whose second element is not an INTEGER tag (e.g. a PKCS#8 PrivateKeyInfo where the first field after SEQUENCE is another SEQUENCE/algorithm identifier).

Common situations: Mixing up PKCS#8 and SEC1 EC key encodings; keys exported in a non-standard or corrupted format; parsing the wrong segment of a concatenated PEM file.

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/7f3eb34395c11329. Report an issue: GitHub.