{"record":{"id":"3938382d25381592","repo":"elastic/elasticsearch","slug":"invalid-der-length-missing","errorCode":null,"errorMessage":"Invalid DER: length missing","messagePattern":"Invalid DER: length missing","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java","lineNumber":127,"sourceCode":"     *          In BER/DER encoding, length can be encoded in 2 forms:\n     * </p>\n     * <ul>\n     * <li>Short form. One octet. Bit 8 has value \"0\" and bits 7-1\n     * give the length.\n     * </li>\n     * <li>Long form. Two to 127 octets (only 4 is supported here).\n     * Bit 8 of first octet has value \"1\" and bits 7-1 give the\n     * number of additional length octets. Second and following\n     * octets give the length, base 256, most significant digit first.\n     * </li>\n     * </ul>\n     *\n     * @return The length as integer\n     */\n    private int getLength() throws IOException {\n\n        int i = derInputStream.read();\n        if (i == -1) throw new IOException(\"Invalid DER: length missing\");\n\n        // A single byte short length\n        if ((i & ~0x7F) == 0) return i;\n\n        int num = i & 0x7F;\n\n        // We can't handle length longer than 4 bytes\n        if (i >= 0xFF || num > 4) throw new IOException(\"Invalid DER: length field too big (\" + i + \")\"); //$NON-NLS-2$\n\n        byte[] bytes = new byte[num];\n        int n = derInputStream.read(bytes);\n        if (n < num) throw new IOException(\"Invalid DER: length too short\");\n\n        int len = new BigInteger(1, bytes).intValue();\n        if (len < 0) {\n            throw new IOException(\"Invalid DER: length larger than max-int\");\n        }\n","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java#L109-L145","documentation":"Thrown by DerParser.getLength() when the very first byte of the length field could not be read (derInputStream.read() returned -1). This means the parser hit end-of-stream immediately after a tag byte, so there is no length octet at all.","triggerScenarios":"Inside getLength(), called from readAsn1Object(): after a tag byte was consumed, the next read() returns -1. Happens when the DER ends right after a tag (length zero or trailing single byte), or when the input was an empty/whitespace byte array handed to DerParser.","commonSituations":"Empty key file, file that contains only a PEM header but no body, base64-decode of an empty string yielding a zero-length byte[], or a corrupted DER that is one byte short.","solutions":["Check that the key file is non-empty: `wc -c keyfile` should report more than a few hundred bytes.","Re-export the key from its source of truth.","If generating the byte[] yourself, assert it is non-empty before constructing DerParser.","Inspect with `openssl pkey -in key.pem -noout` to confirm the file parses externally."],"exampleFix":"// before\nbyte[] empty = Base64.getDecoder().decode(\"\"); // from a stripped PEM\nnew DerParser(empty).readAsn1Object();\n\n// after: guard upstream\nif (der.length == 0) throw new IllegalArgumentException(\"empty DER input\");\nnew DerParser(der).readAsn1Object();","handlingStrategy":"validation","validationCode":"private static void requireNonEmpty(byte[] der) {\n    if (der == null || der.length == 0) {\n        throw new IllegalArgumentException(\"DER input is empty; cannot read length\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reject empty files at the configuration layer before parsing.","Run `wc -c` on key files during deployment scripts.","Use file integrity checks after copy."],"tags":["ssl","der","asn1","keystore","elasticsearch","crypto"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}