elastic/elasticsearch · error · RuntimeException
document is encrypted
Error message
document is encrypted
What it means
RuntimeException('document is encrypted') from TikaImpl#parse when the JVM hits a LinkageError whose message mentions 'bouncycastle'. Elasticsearch intentionally does not ship BouncyCastle, which Tika needs only for public-key-encrypted PDFs; rather than a confusing NoClassDefFoundError, the parser rewrites it to a clear 'document is encrypted' message. Other LinkageErrors are rethrown unwrapped.
Source
Thrown at modules/ingest-attachment/src/main/java/org/elasticsearch/ingest/attachment/TikaImpl.java:80
/** autodetector based on this subset */
private static final AutoDetectParser PARSER_INSTANCE = new AutoDetectParser(PARSERS);
/** singleton tika instance */
private static final Tika TIKA_INSTANCE = new Tika(PARSER_INSTANCE.getDetector(), PARSER_INSTANCE);
/**
* parses with tika, throwing any exception hit while parsing the document
*/
static String parse(final byte content[], final Metadata metadata, final int limit) throws TikaException, IOException {
try {
return TIKA_INSTANCE.parseToString(new ByteArrayInputStream(content), metadata, limit);
} catch (LinkageError e) {
if (e.getMessage().contains("bouncycastle")) {
/*
* Elasticsearch does not ship with bouncycastle. It is only used for public-key-encrypted PDFs, which this module does
* not support anyway.
*/
throw new RuntimeException("document is encrypted", e);
}
throw new RuntimeException(e);
}
}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Decrypt the document offline (remove encryption) before sending it to ingest — the attachment module does not support encrypted files
- If password-protected, strip protection with qpdf/gpg upstream
- Route encrypted documents to a separate pre-processing step that can handle decryption
Example fix
// before: encrypted PDF in field 'data' -> 'document is encrypted' // after (offline pre-processing) qpdf --decrypt input.pdf output.pdf // then ingest output.pdf
Defensive patterns
Strategy: validation
Validate before calling
// Detect encryption upstream and decrypt before ingest:
if (isEncrypted(fileBytes)) {
fileBytes = decryptOffline(fileBytes); // qpdf/gpg
} Try / catch
try { ingest(attachmentPipeline, doc); }
catch (RuntimeException e) {
if ("document is encrypted".equals(e.getMessage())) { routeToManualDecryptQueue(doc); }
else throw e;
} Prevention
- Decrypt documents in a pre-ingest stage — the attachment module will never ship BouncyCastle
- Flag encrypted files at the producer and route them out of the attachment pipeline
- Document that public-key-encrypted PDFs are unsupported
When it happens
Trigger: A PDF (or other format) that is public-key/password encrypted is fed to the attachment processor; Tika attempts decryption, triggers the missing bouncycastle provider, and throws LinkageError.
Common situations: Security-controlled documents; scanned-and-signed PDFs with encryption; documents exported from DMS systems with default encryption.
Related errors
- field [{}] has an attachment field size of [{}] bytes exceed
- field [{}] has an attachment field size of [{}] bytes exceed
- Error parsing document in field [{}]
- field [{}] has an attachment field size of [{}] bytes exceed
- field [{}] is null, cannot parse.
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/bf1b9740eaa174d9.
Report an issue: GitHub.