elastic/elasticsearch · error · IOException
Invalid DER: stream too short, missing value. Could only…
Error message
Invalid DER: stream too short, missing value. Could only read {} out of {} bytes What it means
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.
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.
Example fix
// before: sub-parsing a buffer that was cut short byte[] truncated = Arrays.copyOf(fullDer, fullDer.length - 10); new DerParser(truncated).readAsn1Object(); // after: pass the complete buffer new DerParser(fullDer).readAsn1Object();
Defensive patterns
Strategy: validation
Validate before calling
private static void requireCompleteDer(byte[] der) {
if (der == null || der.length == 0) throw new IllegalArgumentException("empty DER");
int idx = 1;
int lenByte = der[idx++] & 0xFF;
int declared;
if ((lenByte & 0x80) == 0) {
declared = lenByte;
} else {
int num = lenByte & 0x7F;
if (idx + num > der.length) throw new IllegalArgumentException("truncated length field");
declared = 0;
for (int i = 0; i < num; i++) declared = (declared << 8) | (der[idx + i] & 0xFF);
}
if (1 + (declared > 127 ? 1 + (der[1] & 0x7F) : 1) + declared > der.length) {
throw new IllegalArgumentException("declared length " + declared + " exceeds available bytes");
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid DER: can't handle UCS-4 string
- Invalid DER: can't parse primitive entity
- Invalid DER: length field too big
- Invalid DER: length larger than max-int
- Invalid DER: length missing
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/aa7369f97982aceb.
Report an issue: GitHub.
Appendix: source
Thrown at libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/DerParser.java:97
}
public Asn1Object readAsn1Object() throws IOException {
int tag = derInputStream.read();
if (tag == -1) {
throw new IOException("Invalid DER: stream too short, missing tag");
}
int length = getLength();
// getLength() can return any 32 bit integer, so ensure that a corrupted encoding won't
// force us into allocating a very large array
if (length > maxAsnObjectLength) {
throw new IOException(
"Invalid DER: size of ASN.1 object to be parsed appears to be larger than the size of the key file " + "itself."
);
}
byte[] value = new byte[length];
int n = derInputStream.read(value);
if (n < length) {
throw new IOException(
"Invalid DER: stream too short, missing value. " + "Could only read " + n + " out of " + length + " bytes"
);
}
return new Asn1Object(tag, length, value);
}
/**
* Decode the length of the field. Can only support length
* encoding up to 4 octets.
* <p>
* In BER/DER encoding, length can be encoded in 2 forms:
* </p>
* <ul>
* <li>Short form. One octet. Bit 8 has value "0" and bits 7-1
* give the length.
* </li>
* <li>Long form. Two to 127 octets (only 4 is supported here).View on GitHub (pinned to db6a809a66)