Configuring TLS for Kibana encrypts browser sessions, login requests, and API traffic before they leave the client. That keeps credentials, session cookies, and dashboard responses off plain HTTP and gives users a certificate-backed way to confirm that they reached the real Kibana endpoint.
Current Kibana handles two different HTTPS jobs: it can trust Elasticsearch for outbound requests, and it can present its own server certificate for inbound browser traffic. This page covers the browser-facing side by enabling server.ssl.enabled and pointing Kibana at a certificate and private key that match the host name users actually open in the browser. Elastic's current configuration reference still supports either a PEM certificate-plus-key pair or a PKCS#12 keystore, but the PEM path is the clearest fit for a focused single-method guide.
On DEB and RPM installs, these settings usually live in /etc/kibana/kibana.yml and the TLS assets are commonly kept under /etc/kibana. TLS on the Kibana listener does not replace the separate Elasticsearch connection settings that keep Kibana authenticated to the cluster, so finish that path separately if it is not already working. If the private key is encrypted, store server.ssl.keyPassphrase in the Kibana keystore instead of leaving it in plain text.
$ sudo install -o root -g kibana -m 750 -d /etc/kibana/certs
$ sudo install -o root -g kibana -m 644 /tmp/kibana.crt /etc/kibana/certs/kibana.crt $ sudo install -o root -g kibana -m 640 /tmp/kibana.key /etc/kibana/certs/kibana.key $ sudo install -o root -g kibana -m 644 /tmp/kibana-ca.crt /etc/kibana/certs/kibana-ca.crt
The server certificate must include the DNS name or IP address that users actually open in the browser as a Subject Alternative Name, or modern browsers will reject the connection even when the CA is trusted.
$ sudo ls -l /etc/kibana/certs total 12 -rw-r--r-- 1 root kibana 1115 Apr 2 14:09 kibana-ca.crt -rw-r--r-- 1 root kibana 1176 Apr 2 14:09 kibana.crt -rw-r----- 1 root kibana 1704 Apr 2 14:09 kibana.key
Keep the private key readable only by the service account or a group that the kibana process already belongs to.
$ sudoedit /etc/kibana/kibana.yml
Archive installs commonly use /usr/share/kibana/config/kibana.yml instead of /etc/kibana/kibana.yml.
server.ssl.enabled: true server.ssl.certificate: /etc/kibana/certs/kibana.crt server.ssl.key: /etc/kibana/certs/kibana.key
If the certificate arrives as a PKCS#12 bundle, use server.ssl.keystore.path and its matching password setting instead of server.ssl.certificate plus server.ssl.key. Current Elastic docs still treat those options as mutually exclusive.
This page secures incoming browser traffic only. Configure elasticsearch.hosts, elasticsearch.username, and any required trust settings separately when Kibana also needs updated backend connectivity. Related: How to connect Kibana to Elasticsearch
$ printf '%s' '"replace-with-private-key-passphrase"' | sudo -u kibana env KBN_PATH_CONF=/etc/kibana /usr/share/kibana/bin/kibana-keystore add server.ssl.keyPassphrase --stdin --force
Skip this step when the private key is not encrypted. Create the Kibana keystore first if this host does not already have one. Related: How to create a Kibana keystore
Current Elastic docs allow any valid Kibana setting in the keystore, but invalid or extraneous keys can still prevent Kibana from starting.
$ sudo systemctl restart kibana
$ sudo systemctl status kibana --no-pager --full | head -n 12
● kibana.service - Kibana
Loaded: loaded (/usr/lib/systemd/system/kibana.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-04-02 14:18:05 UTC; 23s ago
Docs: https://www.elastic.co
Main PID: 7 (node)
Tasks: 11 (limit: 14335)
Memory: 703.8M (peak: 704.4M)
CPU: 18.662s
##### snipped #####
If the service does not return to active (running), inspect the recent journal for certificate-path, key-permission, YAML, or passphrase errors:
$ sudo journalctl -u kibana -n 50 --no-pager
$ curl --silent --show-error --head --cacert /etc/kibana/certs/kibana-ca.crt https://localhost:5601/login | head -n 6 HTTP/2 200 x-content-type-options: nosniff referrer-policy: strict-origin-when-cross-origin permissions-policy: camera=(), display-capture=(), fullscreen=(self), geolocation=(), microphone=(), web-share=() cross-origin-opener-policy: same-origin content-security-policy: script-src 'report-sample' 'self'; worker-src 'report-sample' 'self' blob:; style-src 'report-sample' 'self' 'unsafe-inline'; object-src 'report-sample' 'none'
A normal 200 OK login response or the expected Kibana security headers confirm that inbound HTTPS is active. If users reach Kibana through a different host name, reverse proxy, or base path, request that published URL instead of https://localhost:5601/login//.</WRAP>
Related: How to check Kibana status
Related: How to set the Kibana public base URL