{"record":{"id":"aa7369f97982aceb","repo":"elastic/elasticsearch","slug":"invalid-der-stream-too-short-missing-value-coul","errorCode":null,"errorMessage":"Invalid DER: stream too short, missing value. Could only read {} out of {} bytes","messagePattern":"Invalid DER: stream too short, missing value\\. Could only read (.+?) out of (.+?) bytes","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java","lineNumber":97,"sourceCode":"    }\n\n    public Asn1Object readAsn1Object() throws IOException {\n        int tag = derInputStream.read();\n        if (tag == -1) {\n            throw new IOException(\"Invalid DER: stream too short, missing tag\");\n        }\n        int length = getLength();\n        // getLength() can return any 32 bit integer, so ensure that a corrupted encoding won't\n        // force us into allocating a very large array\n        if (length > maxAsnObjectLength) {\n            throw new IOException(\n                \"Invalid DER: size of ASN.1 object to be parsed appears to be larger than the size of the key file \" + \"itself.\"\n            );\n        }\n        byte[] value = new byte[length];\n        int n = derInputStream.read(value);\n        if (n < length) {\n            throw new IOException(\n                \"Invalid DER: stream too short, missing value. \" + \"Could only read \" + n + \" out of \" + length + \" bytes\"\n            );\n        }\n        return new Asn1Object(tag, length, value);\n\n    }\n\n    /**\n     * Decode the length of the field. Can only support length\n     * encoding up to 4 octets.\n     * <p>\n     *          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).","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java#L79-L115","documentation":"Thrown by DerParser.readAsn1Object() after allocating a value byte[] of the declared length but reading fewer bytes than requested from derInputStream. The declared length was plausible but the underlying stream ran out of bytes before the value was satisfied.","triggerScenarios":"readAsn1Object() reads a tag, getLength() returns N (N <= maxAsnObjectLength), then InputStream.read(value) returns n < N. Happens on DER blobs whose length octet claims more content than is present — typical of a partial file or a byte array that was sliced incorrectly before being handed to DerParser.","commonSituations":"Key file truncated mid-write (e.g. disk full, scp interrupted), a copy/paste that dropped trailing base64 chars, an off-by-one slice on a DER buffer, or a key that has trailing junk bytes that confuse the length decode of an inner element.","solutions":["Confirm the key file is complete: compare its size against a known-good copy, or re-download/re-export.","Validate the PEM base64 round-trips: `openssl pkey -in key.pem -noout -check` should exit 0.","If slicing a DER buffer programmatically, verify the slice length matches the declared outer SEQUENCE length before sub-parsing.","Regenerate the key with a fresh `openssl genpkey`/`openssl pkcs8` if integrity is doubtful."],"exampleFix":"// before: sub-parsing a buffer that was cut short\nbyte[] truncated = Arrays.copyOf(fullDer, fullDer.length - 10);\nnew DerParser(truncated).readAsn1Object();\n\n// after: pass the complete buffer\nnew DerParser(fullDer).readAsn1Object();","handlingStrategy":"validation","validationCode":"private static void requireCompleteDer(byte[] der) {\n    if (der == null || der.length == 0) throw new IllegalArgumentException(\"empty DER\");\n    int idx = 1;\n    int lenByte = der[idx++] & 0xFF;\n    int declared;\n    if ((lenByte & 0x80) == 0) {\n        declared = lenByte;\n    } else {\n        int num = lenByte & 0x7F;\n        if (idx + num > der.length) throw new IllegalArgumentException(\"truncated length field\");\n        declared = 0;\n        for (int i = 0; i < num; i++) declared = (declared << 8) | (der[idx + i] & 0xFF);\n    }\n    if (1 + (declared > 127 ? 1 + (der[1] & 0x7F) : 1) + declared > der.length) {\n        throw new IllegalArgumentException(\"declared length \" + declared + \" exceeds available bytes\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify the file size matches the declared outer SEQUENCE length before parsing.","Re-download or re-export keys whose length is suspicious.","Use checksums (sha256) to confirm file integrity after transfer."],"tags":["ssl","der","asn1","keystore","elasticsearch","crypto"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}