eclipse-vertx/vert.x · error · RuntimeException
Missing -----END ----- delimiter
Error message
Missing -----END ----- delimiter
What it means
KeyStoreHelper.loadPems() scans a PEM buffer with regexes for BEGIN/END blocks. If a BEGIN ... block has no matching END line after it, a RuntimeException 'Missing -----END <type>----- delimiter' is thrown. This means the PEM text is truncated or malformed.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/net/impl/KeyStoreHelper.java:362
}
}
return keyStore;
}
private static <P> List<P> loadPems(Buffer data, BiFunction<String, byte[], Collection<P>> pemFact) throws IOException {
String pem = data.toString();
List<P> pems = new ArrayList<>();
Matcher beginMatcher = BEGIN_PATTERN.matcher(pem);
Matcher endMatcher = END_PATTERN.matcher(pem);
while (true) {
boolean begin = beginMatcher.find();
if (!begin) {
break;
}
String beginDelimiter = beginMatcher.group(1);
boolean end = endMatcher.find();
if (!end) {
throw new RuntimeException("Missing -----END " + beginDelimiter + "----- delimiter");
} else {
String endDelimiter = endMatcher.group(1);
if (!beginDelimiter.equals(endDelimiter)) {
throw new RuntimeException("Missing -----END " + beginDelimiter + "----- delimiter");
} else {
String content = pem.substring(beginMatcher.end(), endMatcher.start());
content = content.replaceAll("\\s", "");
if (content.length() == 0) {
throw new RuntimeException("Empty pem file");
}
Collection<P> pemItems = pemFact.apply(endDelimiter, Base64.getDecoder().decode(content));
pems.addAll(pemItems);
}
}
}
return pems;
}
View on GitHub (pinned to fb308bd8c3)
Solutions
- Check the file is complete: the last line must be -----END <TYPE>-----; re-download or re-copy the PEM.
- Validate with: openssl x509 -in cert.pem -noout (or openssl pkey -in key.pem -noout) — it fails on truncated files.
- If concatenating multiple PEMs, ensure each block has both BEGIN and END lines.
- Check the secret/configmap was fully mounted (kubectl get secret -o yaml and compare lengths).
Example fix
// before (truncated) -----BEGIN CERTIFICATE----- MIID... // after -----BEGIN CERTIFICATE----- MIID... -----END CERTIFICATE-----
Defensive patterns
Strategy: validation
Validate before calling
String pem = Files.readString(Path.of(pemPath)).trim();
if (!pem.matches("(?s)-----BEGIN [^-]+-----.*-----END [^-]+-----"))
throw new IllegalStateException("PEM file incomplete (missing END delimiter): " + pemPath); Type guard
boolean isCompletePem(String s) {
if (s == null) return false;
long begin = s.split("-----BEGIN", -1).length - 1;
long end = s.split("-----END", -1).length - 1;
return begin > 0 && begin == end;
} Prevention
- Ensure copy/paste and templating preserve the full file including the last line
- Checksum PEM files in CI to catch truncated transfers
- Avoid manual editing of concatenated PEMs; regenerate from source
- Verify with openssl before deploying
When it happens
Trigger: Passing a truncated PEM file (cut-off transfer, partial secret mount) to key/cert options; PEM content programmatically split so the closing END line is missing; extra BEGIN line without a body/end.
Common situations: Secrets truncated by missing final newline handling in CI; copy-paste dropping the last line; HAProxy/nginx config snippets inserted mid-PEM.
Related errors
- Missing -----BEGIN PRIVATE KEY----- or -----BEGIN RSA PRIVAT
- Empty pem file
- Missing -----BEGIN CERTIFICATE----- delimiter
- SSL configuration is necessary for a QUIC server
- Not listening
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/59ce7eed01993b06.
Report an issue: GitHub.