{"record":{"id":"7f3eb34395c11329","repo":"eclipse-vertx/vert.x","slug":"invalid-der-version-field-must-be-of-type-integ","errorCode":null,"errorMessage":"Invalid DER: 'version' field must be of type INTEGER (2) but found type `%d`","messagePattern":"Invalid DER: 'version' field must be of type INTEGER \\(2\\) but found type `(.+?)`","errorType":"exception","errorClass":"VertxException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/net/impl/pkcs1/PrivateKeyParser.java","lineNumber":162,"sourceCode":"   * @see \"https://datatracker.ietf.org/doc/html/rfc5915\"\n   * @param keyBytes The encoded key.\n   * @return The spec that can be used to instantiate the private key.\n   * @throws VertxException if the byte array does not represent an ASN.1 ECPrivateKey structure.\n   */\n  public static ECPrivateKeySpec getECKeySpec(byte[] keyBytes) throws VertxException {\n    DerParser parser = new DerParser(keyBytes);\n\n    Asn1Object sequence = parser.read();\n    if (sequence.getType() != DerParser.SEQUENCE) {\n      throw new VertxException(\"Invalid DER: not a sequence\");\n    }\n\n    // Parse inside the sequence\n    parser = sequence.getParser();\n\n    Asn1Object version = parser.read();\n    if (version.getType() != DerParser.INTEGER) {\n      throw new VertxException(String.format(\n          \"Invalid DER: 'version' field must be of type INTEGER (2) but found type `%d`\",\n          version.getType()));\n    } else if (version.getInteger().intValue() != 1) {\n      throw new VertxException(String.format(\n          \"Invalid DER: expected 'version' field to have value '1' but found '%d'\",\n          version.getInteger().intValue()));\n    }\n    byte[] privateValue = parser.read().getValue();\n    parser = parser.read().getParser();\n    Asn1Object params = parser.read();\n    // ECParameters are mandatory according to RFC 5915, Section 3\n    if (params.getType() != DerParser.OBJECT_IDENTIFIER) {\n      throw new VertxException(String.format(\n          \"Invalid DER: expected to find an OBJECT_IDENTIFIER (6) in 'parameters' but found type '%d'\",\n          params.getType()));\n    }\n    byte[] namedCurveOid = params.getValue();\n    ECParameterSpec spec = getECParameterSpec(oidToString(namedCurveOid));","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/net/impl/pkcs1/PrivateKeyParser.java#L144-L180","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Convert the key to SEC1 form: openssl ec -in key.pem -outform DER.","If the key is PKCS#8, use KeyFactory EC/PKCS8EncodedKeySpec instead of this parser.","Re-export the EC key from the source ensuring RFC 5915 layout.","Validate structure with openssl asn1parse to confirm the version field is INTEGER 1."],"exampleFix":"// before\nECPrivateKeySpec spec = PrivateKeyParser.getECKeySpec(pkcs8Bytes);\n// after\nopenssl ec -in key.pkcs8.pem -outform DER -out key.sec1.der\nECPrivateKeySpec spec = PrivateKeyParser.getECKeySpec(Files.readAllBytes(Path.of(\"key.sec1.der\")));","handlingStrategy":"validation","validationCode":"// Ensure input is SEC1 ECPrivateKey, not PKCS#8 (PKCS#8 has a second SEQUENCE after version)\nbyte[] der = Base64.getMimeDecoder().decode(pemBody);\nboolean looksLikePkcs8 = der.length > 4 && der[0] == 0x30 && der[1] > 40; // heuristic; verify with openssl asn1parse\nif (pemHeader.contains(\"PRIVATE KEY\") && !pemHeader.contains(\"EC PRIVATE KEY\")) {\n    throw new IllegalArgumentException(\"Use SEC1 'EC PRIVATE KEY' PEM for getECKeySpec\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return PrivateKeyParser.getECKeySpec(der);\n} catch (VertxException e) {\n    if (e.getMessage().contains(\"version\")) {\n        throw new KeyFormatException(\"Wrong key encoding for EC parser: \" + e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Keep PEM headers and parser pairing explicit (BEGIN EC PRIVATE KEY -> getECKeySpec)","Convert PKCS#8 to SEC1 with openssl ec -in key.pkcs8.pem","Check encoding with openssl asn1parse -i"],"tags":["der","asn1","ec","version-field","format"],"backgroundTag":"invalid-argument-format","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}