TLS/SSL Configuration
Tika Server supports TLS (Transport Layer Security) for encrypted communication and mutual authentication (2-way TLS / mTLS).
Choosing a Security Approach
For most deployments, we recommend placing Tika Server behind a reverse proxy (such as nginx, Apache httpd, or Traefik) that handles TLS termination. This approach simplifies certificate management, enables additional features like rate limiting and authentication, and follows a well-established pattern with extensive documentation. In this setup, the reverse proxy handles HTTPS connections from clients, and Tika Server runs on plain HTTP in a private network or on localhost. If you need token-based authentication (JWT, API keys, OAuth2), an API gateway or reverse proxy with authentication modules is the recommended approach, as Tika Server does not include built-in token support.
Direct TLS configuration on Tika Server (described in this document) is useful when you cannot use a reverse proxy, need client certificate authentication (2-way TLS/mTLS), or prefer a simpler single-process deployment. If you only need to restrict access without TLS, consider network-level controls such as binding to localhost, firewall rules, or running in a private subnet.
Overview
TLS configuration options:
-
1-Way TLS: Server presents its certificate; clients verify the server
-
2-Way TLS (mTLS): Both server and client present certificates for mutual authentication
Quick Start
1-Way TLS
Server authenticates to clients, but clients are not required to present certificates.
{
"server": {
"host": "localhost",
"port": 9998
},
"tlsConfig": {
"active": true,
"keyStoreType": "PKCS12",
"keyStoreFile": "/path/to/server-keystore.p12",
"keyStorePassword": "your-password",
"clientAuthenticationWanted": false,
"clientAuthenticationRequired": false
}
}
2-Way TLS (mTLS)
Both server and client must present valid certificates.
{
"server": {
"host": "localhost",
"port": 9998
},
"tlsConfig": {
"active": true,
"keyStoreType": "PKCS12",
"keyStoreFile": "/path/to/server-keystore.p12",
"keyStorePassword": "your-password",
"trustStoreType": "PKCS12",
"trustStoreFile": "/path/to/server-truststore.p12",
"trustStorePassword": "your-password",
"clientAuthenticationWanted": true,
"clientAuthenticationRequired": true
}
}
Docker Deployment
When running Tika Server in Docker with TLS, you need to:
-
Create a configuration file with TLS settings
-
Mount the configuration file into the container
-
Mount the keystore (and truststore for 2-way TLS) into the container
-
Start the container with the
-cflag pointing to the config file
Directory Structure
Create a directory structure on your host machine:
tika-tls/
├── config/
│ └── tika-config.json
└── certs/
├── server-keystore.p12
└── server-truststore.p12 # (for 2-way TLS)
Configuration File
Create tika-tls/config/tika-config.json:
{
"server": {
"host": "0.0.0.0",
"port": 9998
},
"tlsConfig": {
"active": true,
"keyStoreType": "PKCS12",
"keyStoreFile": "/tika/certs/server-keystore.p12",
"keyStorePassword": "your-password",
"trustStoreType": "PKCS12",
"trustStoreFile": "/tika/certs/server-truststore.p12",
"trustStorePassword": "your-password",
"clientAuthenticationRequired": true
}
}
Use 0.0.0.0 as the host to bind to all interfaces inside the container.
The paths (/tika/certs/…) must match where you mount the files in the container.
|
Running with Docker
docker run -d \
--name tika-server \
-p 9998:9998 \
-v $(pwd)/tika-tls/config:/tika/config:ro \
-v $(pwd)/tika-tls/certs:/tika/certs:ro \
apache/tika:<version> \
-c /tika/config/tika-config.json
Options explained:
-
-p 9998:9998- Expose the HTTPS port -
-v …/config:/tika/config:ro- Mount config directory (read-only) -
-v …/certs:/tika/certs:ro- Mount certificates directory (read-only) -
-c /tika/config/tika-config.json- Path to config file inside container
Docker Compose
For more complex deployments, use Docker Compose:
# docker-compose.yml
version: '3.8'
services:
tika:
image: apache/tika:latest
ports:
- "9998:9998"
volumes:
- ./config:/tika/config:ro
- ./certs:/tika/certs:ro
command: ["-c", "/tika/config/tika-config.json"]
healthcheck:
test: ["CMD", "curl", "-f", "--cacert", "/tika/certs/server.crt", "https://localhost:9998/tika"]
interval: 30s
timeout: 10s
retries: 3
Run with:
docker-compose up -d
Using Secrets (Docker Swarm / Kubernetes)
For production deployments, avoid storing passwords in plain text config files.
Docker Swarm
Use Docker secrets for sensitive data:
# Create secrets
echo "your-keystore-password" | docker secret create tika_keystore_password -
echo "your-truststore-password" | docker secret create tika_truststore_password -
# Reference in docker-compose.yml (swarm mode)
services:
tika:
image: apache/tika:latest
secrets:
- tika_keystore_password
- tika_truststore_password
# Read password from /run/secrets/tika_keystore_password in entrypoint script
Kubernetes
Use Kubernetes secrets:
# Create secret for certificates
kubectl create secret generic tika-tls-certs \
--from-file=server-keystore.p12=./certs/server-keystore.p12 \
--from-file=server-truststore.p12=./certs/server-truststore.p12
# Create secret for passwords
kubectl create secret generic tika-tls-passwords \
--from-literal=keystore-password=your-password \
--from-literal=truststore-password=your-password
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tika-server
spec:
replicas: 1
selector:
matchLabels:
app: tika
template:
metadata:
labels:
app: tika
spec:
containers:
- name: tika
image: apache/tika:latest
ports:
- containerPort: 9998
args: ["-c", "/tika/config/tika-config.json"]
volumeMounts:
- name: config
mountPath: /tika/config
readOnly: true
- name: certs
mountPath: /tika/certs
readOnly: true
env:
- name: KEYSTORE_PASSWORD
valueFrom:
secretKeyRef:
name: tika-tls-passwords
key: keystore-password
volumes:
- name: config
configMap:
name: tika-config
- name: certs
secret:
secretName: tika-tls-certs
Testing Docker TLS Setup
Test that TLS is working:
# 1-way TLS (trust server certificate)
curl --cacert ./certs/server.crt https://localhost:9998/tika
# 2-way TLS (provide client certificate)
curl --cacert ./certs/server.crt \
--cert ./certs/client.crt \
--key ./certs/client-key.pem \
https://localhost:9998/tika
If using self-signed certificates and just testing:
# Skip certificate verification (NOT for production!)
curl -k https://localhost:9998/tika
Configuration Reference
tlsConfig Properties
| Property | Type | Default | Description |
|---|---|---|---|
|
boolean |
false |
Enable TLS. When true, the server uses HTTPS. |
|
string |
null |
Keystore format: |
|
string |
null |
Path to the server’s keystore file containing its private key and certificate. |
|
string |
null |
Password for the keystore. |
|
string |
null |
Truststore format: |
|
string |
null |
Path to the truststore containing trusted client certificates (for 2-way TLS). |
|
string |
null |
Password for the truststore. |
|
boolean |
false |
Request client certificates but don’t require them. Clients without certificates can still connect. |
|
boolean |
false |
Require client certificates. Clients must present a valid certificate trusted by the server. |
|
list |
["TLSv1.2", "TLSv1.3"] |
TLS protocol versions to enable. Default only allows TLS 1.2 and 1.3. |
|
list |
null |
TLS protocol versions to explicitly disable. |
|
list |
null |
Cipher suites to enable. If null, uses JVM defaults. |
|
list |
null |
Cipher suites to disable. |
|
integer |
30 |
Days before certificate expiration to log warnings. Set to 0 to disable. |
Certificate Expiration Warnings
Tika Server automatically checks certificate expiration at startup and logs warnings for certificates that will expire soon. This helps prevent unexpected outages due to expired certificates.
Warning Levels
-
ERROR: Certificate has already expired or is not yet valid - TLS will fail
-
WARN: Certificate expires within the configured threshold (default: 30 days)
-
DEBUG: Certificate is valid (logged at debug level)
Example Log Output
WARN TlsConfig - Certificate 'server' in keystore expires in 15 days on Sat Feb 15 12:00:00 UTC 2026. Consider renewing soon.
ERROR TlsConfig - Certificate 'server' in keystore has EXPIRED on Mon Jan 01 12:00:00 UTC 2026. TLS connections will fail!
Configuring the Warning Threshold
To change when warnings are logged (default is 30 days before expiration):
{
"tlsConfig": {
"active": true,
"keyStoreType": "PKCS12",
"keyStoreFile": "/path/to/server-keystore.p12",
"keyStorePassword": "your-password",
"certExpirationWarningDays": 60
}
}
Set to 0 to disable expiration checking.
Generating Certificates
This section shows how to generate self-signed certificates for testing. For production, use certificates from a trusted Certificate Authority (CA).
Generate Server Keystore
# Generate server private key and certificate
keytool -genkeypair \
-alias server \
-keyalg RSA \
-keysize 2048 \
-validity 365 \
-keystore server-keystore.p12 \
-storetype PKCS12 \
-storepass changeit \
-dname "CN=localhost,OU=Tika,O=Apache,L=Unknown,ST=Unknown,C=US"
# Export server certificate (for clients to trust)
keytool -exportcert \
-alias server \
-keystore server-keystore.p12 \
-storetype PKCS12 \
-storepass changeit \
-file server.crt
Generate Client Keystore (for 2-Way TLS)
# Generate client private key and certificate
keytool -genkeypair \
-alias client \
-keyalg RSA \
-keysize 2048 \
-validity 365 \
-keystore client-keystore.p12 \
-storetype PKCS12 \
-storepass changeit \
-dname "CN=TikaClient,OU=Tika,O=Apache,L=Unknown,ST=Unknown,C=US"
# Export client certificate (for server to trust)
keytool -exportcert \
-alias client \
-keystore client-keystore.p12 \
-storetype PKCS12 \
-storepass changeit \
-file client.crt
Create Truststores
# Create server truststore (import client certificate)
keytool -importcert \
-alias client \
-file client.crt \
-keystore server-truststore.p12 \
-storetype PKCS12 \
-storepass changeit \
-noprompt
# Create client truststore (import server certificate)
keytool -importcert \
-alias server \
-file server.crt \
-keystore client-truststore.p12 \
-storetype PKCS12 \
-storepass changeit \
-noprompt
Protocol and Cipher Configuration
Restricting TLS Versions
By default, only TLS 1.2 and TLS 1.3 are enabled. TLS 1.0 and 1.1 are considered insecure and are not enabled by default.
To use only TLS 1.3:
{
"tlsConfig": {
"active": true,
"keyStoreType": "PKCS12",
"keyStoreFile": "/path/to/server-keystore.p12",
"keyStorePassword": "your-password",
"includedProtocols": ["TLSv1.3"]
}
}
Restricting Cipher Suites
To allow only specific cipher suites:
{
"tlsConfig": {
"active": true,
"keyStoreType": "PKCS12",
"keyStoreFile": "/path/to/server-keystore.p12",
"keyStorePassword": "your-password",
"includedCipherSuites": [
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
]
}
}
To exclude weak cipher suites:
{
"tlsConfig": {
"active": true,
"keyStoreType": "PKCS12",
"keyStoreFile": "/path/to/server-keystore.p12",
"keyStorePassword": "your-password",
"excludedCipherSuites": [
".*CBC.*",
".*RC4.*",
".*3DES.*",
".*NULL.*"
]
}
}
Testing TLS Configuration
Test with curl (1-Way TLS)
# Trust the server certificate
curl --cacert server.crt https://localhost:9998/tika
Test with curl (2-Way TLS)
# Provide client certificate and trust server certificate
curl --cacert server.crt \
--cert client.crt \
--key client-key.pem \
https://localhost:9998/tika
Test with Java Client
// Configure SSL context for 2-way TLS
SSLContext sslContext = SSLContexts.custom()
.loadKeyMaterial(
new File("client-keystore.p12"),
"changeit".toCharArray(),
"changeit".toCharArray())
.loadTrustMaterial(
new File("client-truststore.p12"),
"changeit".toCharArray())
.build();
HttpClient client = HttpClients.custom()
.setSSLContext(sslContext)
.build();
HttpGet request = new HttpGet("https://localhost:9998/tika");
HttpResponse response = client.execute(request);
Security Best Practices
-
Use strong passwords for keystores and truststores
-
Use TLS 1.2 or 1.3 only (default configuration)
-
Prefer PKCS12 format over JKS (better interoperability)
-
Use certificates from a trusted CA in production
-
Rotate certificates before they expire
-
Restrict cipher suites to strong, modern algorithms
-
Use 2-way TLS when clients need to be authenticated
-
Protect keystore files with appropriate file system permissions
-
Never commit passwords to version control; use environment variables or secrets management
Troubleshooting
Common Errors
"keyStoreFile does not exist or is not a file"
The specified keystore file path is incorrect or the file doesn’t exist. Verify the path is absolute or relative to the working directory.
"Partial truststore configuration detected"
You’ve set some but not all truststore properties. Either set all three
(trustStoreType, trustStoreFile, trustStorePassword) or none.
"requiring client authentication, but no trust store has been specified"
You’ve set clientAuthenticationRequired: true but haven’t configured a truststore.
The server needs a truststore to verify client certificates.
SSL handshake failures
-
Verify certificates are valid and not expired
-
Ensure client trusts server certificate (for 1-way TLS)
-
Ensure server trusts client certificate (for 2-way TLS)
-
Check that protocol versions and cipher suites are compatible
See Also
-
Security - General security considerations
-
Robustness - Process isolation and fault tolerance