{"record":{"id":"7ccb03e0737c96cc","repo":"elastic/elasticsearch","slug":"invalid-der-can-t-parse-primitive-entity","errorCode":null,"errorMessage":"Invalid DER: can't parse primitive entity","messagePattern":"Invalid DER: can't parse primitive entity","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java","lineNumber":217,"sourceCode":"            return length;\n        }\n\n        public byte[] getValue() {\n            return value;\n        }\n\n        public boolean isConstructed() {\n            return (tag & DerParser.CONSTRUCTED) == DerParser.CONSTRUCTED;\n        }\n\n        /**\n         * For constructed field, return a parser for its content.\n         *\n         * @return A parser for the construct.\n         */\n        public DerParser getParser() throws IOException {\n            if (isConstructed() == false) {\n                throw new IOException(\"Invalid DER: can't parse primitive entity\"); //$NON-NLS-1$\n            }\n\n            return new DerParser(value);\n        }\n\n        /**\n         * Get the value as integer\n         *\n         * @return BigInteger\n         */\n        public BigInteger getInteger() throws IOException {\n            if (type != Type.INTEGER) throw new IOException(\"Invalid DER: object is not integer\"); //$NON-NLS-1$\n\n            return new BigInteger(value);\n        }\n\n        public String getString() throws IOException {\n","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java#L199-L235","documentation":"Thrown by Asn1Object.getParser() when getParser() is called on a primitive (non-constructed) ASN.1 entity. Only constructed entities (tag bit 0x20 set, e.g. SEQUENCE, SET) have nested content that can be re-parsed; primitive entities hold a leaf value.","triggerScenarios":"Code calls asn1Object.getParser() on an object whose CONSTRUCTED bit (0x20) is not set. Common in parseEcDer (line 607) where the code calls choice.getParser() on the third element — if the input is misencoded and that element is primitive instead of constructed, this fires.","commonSituations":"Malformed EC private key where the expected [0] or [1] tagged constructed element is encoded as primitive, or a DER blob whose structure does not match the expected PKCS#1/PKCS#8/SEC1 layout.","solutions":["Regenerate the key with a standard tool: `openssl ecparam -genkey -name prime256v1 -out ec.pem` or `openssl pkcs8 -topk8`.","If you are parsing custom DER, re-check the expected schema and ensure you only call getParser() on constructed elements.","Use `isConstructed()` as a guard before calling getParser() to produce a clearer error.","Inspect with `openssl asn1parse -inform DER -in key.der` to verify element types."],"exampleFix":"// before: unconditional sub-parse\nDerParser.Asn1Object choice = parser.readAsn1Object();\nDerParser inner = choice.getParser(); // throws if primitive\n\n// after: guard the call\nif (choice.isConstructed() == false) {\n    throw new IOException(\"expected constructed element but found primitive tag 0x\" + Integer.toHexString(choice.getTag()));\n}\nDerParser inner = choice.getParser();","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"public static boolean isConstructed(DerParser.Asn1Object o) {\n    return o != null && o.isConstructed();\n}\n\n// Usage:\n// DerParser.Asn1Object elem = parser.readAsn1Object();\n// if (!isConstructed(elem)) throw new IOException(\"expected constructed element\");\n// DerParser inner = elem.getParser();","tryCatchPattern":null,"preventionTips":["Always check isConstructed() before calling getParser().","Validate element types against the expected schema before descending.","Prefer PKCS#8 keys to avoid complex nested DER parsing paths."],"tags":["ssl","der","asn1","keystore","elasticsearch","crypto"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}