Debugging Elasticsearch and Lucene with IntelliJ IDEA

WARNING: As of Elasticsearch version 7.5, these instructions no longer work.


IntelliJ IDEA is a Java integrated development environment (IDE) for developing computer software. In this blog post, I discuss how to setup an IntelliJ IDEA project that will allow interactive debugging of Elasticsearch and Lucene source code.

The instructions presented in this blog have been tested on Mac OSX with IntelliJ IDEA 2018.3 (Community Edition), OpenJDK 11, and Elasticsearch 6.6.

Download Elasticsearch

Get a copy of the Elasticsearch source code from github as follows:

git clone

Checkout the branch for the Elasticsearch release that you want to debug.

cd elasticsearch
git checkout --track origin/6.6

Review text files included with the distribution

Within the “elasticsearch” directory, there are several text files that should be reviewed. In particular, “” includes a description of the process for importing Elasticsearch code into an IntelliJ IDEA project, and “TESTING.asciidoc” describes ways to build and debug the code. The remainder of this blog post is based on the instructions in these files.

Configure the code for use with IntelliJ IDEA

The build system used by Elasticsearch is gradle, and at least Java 11 is required to build Elasticsearch gradle tools. Before executing gradlew, ensure that your JAVA_HOME environment variable is set correctly. For example my JAVA_HOME (on OSX) is set as follows:

export JAVA_HOME 

Finally, execute the following command to configure Elasticsearch for use in an IntelliJ IDEA project.

./gradlew idea

The above command may take a few minutes to execute, and once it is complete, your project is ready to be imported into IntelliJ IDEA.

Import Elasticsearch into an IntelliJ IDEA project

1. Open IntelliJ Idea, and if you don’t have any other projects open, you will see a screen that looks like the image below. Click on “Import project”

Screen Shot 2019-02-02 at 8.56.52 PM

2. Open the “elasticsearch” directory that was created by the previously executed “git clone” command.

Screen Shot 2019-02-02 at 9.22.19 PM

3. Select “Import project from external model” -> “Gradle”, and the click on “Next”

Screen Shot 2019-02-02 at 9.28.06 PM

4. Select “Use default gradle wrapper (recommended)” and set “Gradle JVM” to version 11, as shown below. Then click on “Finish”.

Screen Shot 2019-02-02 at 9.28.36 PM

5. After completing the above steps, IntelliJ IDEA will start building the source code. The IntelliJ IDEA window should look similar to the image below once the build has completed.

Screen Shot 2019-02-02 at 9.36.27 PM

Start Elasticsearch for debugging

One way to debug Elasticsearch is to start the project in debug mode from the command line with the following command:

./gradlew run --debug-jvm

It may take a few minutes for the above process to fully start, at which point you can connect to the process from IntelliJ IDEA  by clicking on “Run” -> “Attach to Process” as shown below:

Screen Shot 2019-02-02 at 9.49.47 PM.png

This will allow you to select the process to attach to, which should look similar to the following:

Screen Shot 2019-02-02 at 9.53.27 PM

You should now be able to set breakpoints and step through both Elasticsearch and Lucene code.


In this blog post, I have demonstrated how to setup a project in IntelliJ IDEA that will allow interactive debugging of Elasticsearch and Lucene source code. You are now ready to dig deep into the internal workings of Elasticsearch!

A step-by-step guide to enabling security, TLS/SSL, and PKI authentication in Elasticsearch


When Elasticsearch security is enabled for a cluster that is running with a production license, the use of TLS/SSL for transport communications is obligatory and must be correctly setup. Additionally, once security has been enabled, all communications to an Elasticsearch cluster must be authenticated, including communications from Kibana and/or application servers.

The simplest way that Kibana and/or application servers can authenticate to an Elasticsearch cluster is by embedding a username and password in their configuration files or source code. However, in many organizations, it is forbidden to store usernames and passwords in such locations. In this case, one alternative is to use Public Key Infrastructure (PKI) (client certificates) for authenticating to an Elasticsearch cluster.

Configuring security along with TLS/SSL and PKI can seem daunting at first, and so this blog gives step-by-step instructions on how to: enable security; configure TLS/SSL; set passwords for built-in users; use PKI for authentication; and finally, how to authenticate Kibana to an Elasticsearch cluster using PKI.

Enabling security

In order to enable security it is necessary to have either a Gold or Platinum subscription, or a trial license enabled via Kibana or API. For example, the following command would enable a trial license via the API:

curl -X POST "localhost:9200/_xpack/license/start_trial?acknowledge=true"

Where localhost must be replaced with the name of a node in our Elasticsearch cluster.

After enabling a license, security can be enabled. We must modify the elasticsearch.yml file on each node in the cluster with the following line: true

For a cluster that is running in production mode with a production license, once security is enabled, transport TLS/SSL must also be enabled. However, if we are running with a trial license, then transport TLS/SSL is not obligatory.

If we are running with a production license and we attempt to start the cluster with security enabled before we have enabled transport TLS/SSL, we will see the following error message:

Transport SSL must be enabled for setups with production licenses. Please set [] to [true] or disable security by setting [] to [false]

Configuration of TLS/SSL is covered in the following sections.

TLS/SSL encryption

Elasticsearch has two levels of communications, transport communications and http communications. The transport protocol is used for internal communications between Elasticsearch nodes, and the http protocol is used for communications from clients to the Elasticsearch cluster. Securing these communications will be discussed in the following paragraphs.

Transport TLS/SSL encryption

The transport protocol is used for communication between nodes within an Elasticsearch cluster. Because each node in an Elasticsearch cluster is both a client and a server to other nodes in the cluster, all transport certificates must be both client and server certificates. If TLS/SSL certificates do not have Extended Key Usage defined, then they are already defacto client and server certificates. If transport certificates do have an Extended Key Usage section, which is usually the case for CA-signed certificates used in corporate environments, then they must explicitly enable both clientAuth and serverAuth.

Note that Elasticsearch comes with a utility called elasticsearch-certutil that can be used for generating self-signed certificates that can be used for encrypting internal communications within an Elasticsearch cluster.

The following commands can be used for generating certificates that can be used for transport communications, as described in this page on Encrypting Communications in Elasticsearch:

bin/elasticsearch-certutil ca
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

Once the above commands have been executed, we will have TLS/ SSL certificates that can be used for encrypting communications.

The newly created certificates should be copied into a sub-directory called certs located within the config directory. The certificates will then be specified in the elasticsearch.yml file as follows: true certificate certs/elastic-certificates.p12 certs/elastic-certificates.p12

Now restart all of the nodes in our Elasticsearch cluster for the above changes to take effect.

Define built-in user’s passwords

We must now define passwords for the built-in users as described in Setting built-in user passwords. Note that if we are running with a Gold or Platinum license, the previous steps to enable TLS/SSL for the transport communications must be executed before the cluster will start. Additionally, note that setting built-in user’s passwords should be completed before we enable TLS/SSL for http communications, as the command for setting passwords will communicate with the cluster via unsecured http.

Built-in users passwords can be setup with the following command:

bin/elasticsearch-setup-passwords interactive

Be sure to remember the passwords that we have assigned for each of the built-in users. We will make use of the elastic superuser to help configure PKI authentication later in this blog.

Http TLS/SSL encryption

For http communications, the Elasticsearch nodes will only act as servers and therefore can use Server certificates —  i.e. http TLS/SSL certificates do not need to enable Client authentication.

In many cases, certificates for http communications would be signed by a corporate CA. It is worth noting that the certificates used for encrypting http communications can be totally independent from the certificates that are used for transport communications.

To reduce the number of steps in this blog, we’ll use the same certificates for http communications as we have already used for the transport communications. These are specified in elasticsearch.yml file as follows: true certs/elastic-certificates.p12 certs/elastic-certificates.p12 optional

Enabling PKI authentication

As discussed in Configuring a PKI Realm, the following must be added to the elasticsearch.yml file to allow PKI authentication. pki

Combined changes to elasticsearch.yml

Once the above steps have been followed, we should have the following defined in our elasticsearch.yml configuration: true true certificate certs/elastic-certificates.p12 certs/elastic-certificates.p12 true certs/elastic-certificates.p12 certs/elastic-certificates.p12 optional pki

Note that once the above changes have been made to our elasticsearch.yml file, we will have to restart all of the Elasticsearch nodes in our cluster in order for the changes to take effect.

Creating a client certificate

Certificates that will be used for PKI authentication must be signed by the same CA as the certificates that are used for encrypting http communications. Normally, these would be signed by an official CA within an organization. However, because we have already used a self signed CA, we also sign our http client certificates with that same self-signed CA which we previously saved as elastic-stack-ca.p12. We can create a certificate for client authentication as follows:

bin/elasticsearch-certutil cert --ca \
config/certs/elastic-stack-ca.p12 \
-name "CN=something,OU=Consulting Team,DC=mydomain,DC=com"
client.p12 ENTER

The above will create a file called client.p12, which contains all of the information required for PKI authentication to our Elasticsearch cluster. However, in order to use this certificate it is helpful to break it into its private key, public certificate, and CA certificate. This can be done with the following commands:

Private Key

openssl pkcs12 -in client.p12 -nocerts -nodes  > client.key

Public Certificate

openssl pkcs12 -in client.p12 -clcerts -nokeys  > client.cer

CA Certificate

openssl pkcs12 -in client.p12 -cacerts -nokeys -chain > client-ca.cer

Which should produce three files,

  1. client.key —  The private key
  2. client.cer —  The public certificate
  3. client-ca.cer — The CA that signed the public certificate

Create a directory called certs in Kibana’s config directory, and move all of the client certificates there.

Configure Kibana to authenticate to elasticsearch

Now that we have enabled security on the Elasticsearch cluster, communications to the cluster must be authenticated. Therefore, if we plan on using Kibana to interact with the cluster, then we must enable security and configure Kibana to authenticate to the cluster as the kibana user over https. As we have not yet fully setup PKI authentication from Kibana to the Elasticsearch cluster, authentication can initially be done with the following lines in the kibana.yml file:

elasticsearch.url: "https://localhost:9200" #ensure https not http true
elasticsearch.username: "kibana"
elasticsearch.password: "our new kibana password here"
elasticsearch.ssl.certificateAuthorities: config/certs/client-ca.cer
elasticsearch.ssl.verificationMode: certificate

Ensure that we change localhost to the name of one of our Elasticsearch nodes, and that the certificates are available in the config/certs directory within the Kibana folder.

Note that the kibana user is like a service account that works behind the scenes to authenticate the Kibana application to the Elasticsearch cluster. We will generally never directly login to the Elasticsearch cluster or into the Kibana UI as the kibana user.

Restart Kibana in order for it to authenticate to the Elasticsearch cluster as the kibana user. We should be able to now login through the Kibana UI as the elastic built-in superuser.

PKI Authentication

We can use the three new client certificate files to test PKI authentication to the cluster with curl. Open a new terminal and cd to Kibana’s config/certs directory, and use curl to call the authenticate API as shown below.

curl https://localhost:9200/_xpack/security/_authenticate?pretty \
--key client.key --cert client.cer --cacert client-ca.cer -k -v

Be sure to replace localhost with the name of a node in our Elasticsearch cluster and be sure to use https (not http). Also note that the -k option is required as we did not create certificates with the hostnames specified, and therefore hostname verification must be turned off.

The above command should respond with something similar to the following:

 "username" : "something",
 "roles" : [ ],
 "full_name" : null,
 "email" : null,
 "metadata" : {
   "pki_dn" : "CN=something, OU=Consulting Team, DC=mydomain, DC=com"
 "enabled" : true

Notice that the roles is currently empty which means that although we have authenticated to Elasticsearch, we are not authorized to perform any actions. Authentication is allowed because the client certificate that we sent to the cluster was signed by the same CA as the http TLS/SSL certificates used by the Elasticsearch nodes. Now that we are authenticated, we need to authorize this user to be able to do something.

The pki_dn value returned from the authenticate API will be used to configure the roles that will be assigned to this certificate.

Open the Kibana UI and if we have not already done so, login as the elastic user. As the elastic user has superuser privileges, this user can assign roles to the certificate. Execute the following command from Dev Tools in Kibana, ensuring that the previously returned pki_dn value is copied into the dn field as follows:

PUT _xpack/security/role_mapping/kibana_certificate_authorization
 "roles" : [ "kibana_system" ],
 "rules" : { "field" : { "dn" : "CN=something, OU=Consulting Team, DC=mydomain, DC=com" } },
 "enabled": true

Now that we have assigned kibana_system role to this certificate, verify this is set correctly with another call to the authenticate API:

curl https://localhost:9200/_xpack/security/_authenticate?pretty \
--key client.key --cert client.cer --cacert client-ca.cer -k -v

And we should see the following response, which indicates that we now have the “kibana_system” role assigned to this certificate.

 "username" : "something",
 "roles" : [

 "full_name" : null,
 "email" : null,
 "metadata" : {
   "pki_dn" : "CN=something, OU=Consulting Team, DC=mydomain, DC=com"
 "enabled" : true

Using PKI to authenticate Kibana to the Elasticsearch cluster

Now that we have tested our client-side certificate and assigned the kibana_system role to the certificate, we can use this certificate instead of a username and password, to authenticate Kibana to Elasticsearch.

Remove the following lines from our kibana.yml file:

elasticsearch.username: "kibana"
elasticsearch.password: "XXXXXX"

Ensure that all relevant certificates are copied to Kibana’s config/certs directory, and add the following lines to our kibana.yml file:

elasticsearch.url: "https://localhost:9200" #ensure https true
elasticsearch.ssl.certificate: config/certs/client.cer
elasticsearch.ssl.key: config/certs/client.key
elasticsearch.ssl.certificateAuthorities: config/certs/client-ca.cer
elasticsearch.ssl.verificationMode: certificate

We can now restart Kibana, and it should authenticate to our Elasticsearch cluster, without any need for an embedded username and password!


In this blog post, I have demonstrated how to: enable security; configure TLS/SSL; set passwords for built-in users; use PKI for authentication; and finally, how to authenticate Kibana to an Elasticsearch cluster using PKI.

If you have any questions about PKI authentication with Elasticsearch, or any other Elasticsearch-related topics, have a look at our Discuss forums for valuable discussion,  insights, and information.