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

  1. Decrypt the document offline (remove encryption) before sending it to ingest — the attachment module does not support encrypted files
  2. If password-protected, strip protection with qpdf/gpg upstream
  3. 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

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


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/bf1b9740eaa174d9. Report an issue: GitHub.