Table of Contents


To support encryption of connections you need to supply Prosody with a certificate and a key file in the standard PEM format.

If you run other encrypted services such as a HTTPS website or mail server then you may have these already and can simply direct Prosody to use them. Otherwise you will need to obtain some.

Which domain?

Sometimes there is confusion about which domain to get a certificate for, if your service uses SRV records to delegate XMPP services to a second domain (e.g.

The answer is simple - your certificate simply needs to match whatever you have in your VirtualHost and Component definitions (e.g. and, as these are the services you need to authenticate as. When you use the prosodyctl cert commands (see below), the correct entries are always included.

Obtaining a certificate

If you do not currently have certificates, you have several options:

Using Let's Encrypt

There are multiple ways to integrate Prosody and Let's Encrypt. This section describes our recommended setup.

Ubuntu LTS

Debian stable, oldstable

Link to diff page

Using other certificate authorities

Any recognised certificate authority can provide certificates for you, usually for a fee, valid for a certain period of time (usually a year).

*Note:* StartSSL (StartCom) used to be popular within the XMPP community. Their certificates are no longer recommended. For a free alternative, consider using Let's Encrypt instead.

CAs will usually ask you to send them a certificate signing request (CSR). Prosody can generate one for you based on any host in your config. Simply run:

  prosodyctl cert request

If you are running Prosody 0.9, you will need to copy the .key file that this command generates and put it into your certificate directory (e.g. /etc/prosody/certs/ Ensure that this file is readable by Prosody only. The .req file that this command generates should be provided to your CA.

After the CA provides you with your new certificate, proceed to installing the certificate.

Creating self-signed certificates

Instead of using a certificate authority, you can create a "self-signed" certificate instead. These are quick and easy to create, but they will show security warnings in clients, and some clients or other servers may refuse to connect to your server entirely.

Prosody makes it easy to produce a self-signed certificate from a host in your config file. Simply run:

  prosodyctl cert generate

For versions before 0.9, you can run openssl manually like so:

 openssl req -new -x509 -days 365 -nodes -out "" -newkey rsa:2048 -keyout ""

Enter the information openssl asks for, it will be encoded in the certificate, and what you enter isn't too important, except ensure that when it asks for the "Common Name (eg, YOUR name)" you must enter the domain of your Prosody server (that is, whatever you defined with VirtualHost in the Prosody config file).

In Prosody 0.10 the generated certificate can be used immediately after running prosodyctl reload, if you have not changed the certificate path in the config file.

In earlier versions of Prosody, you will need to copy the generated .key and .crt file to an appropriate place (e.g. /etc/prosody/certs) and set the appropriate permissions.

Installing the certificate

Prosody needs both the certificate and key file. We recommend copying these to the 'certs' subdirectory in the config directory.

For example, if your config file is in /etc/prosody/prosody.cfg.lua:

If you are using Prosody 0.10 or later, these files will be located automatically.

If your certificate and key are not in the default location, you can set the 'certificate' option:

VirtualHost ""
  -- Override automatic location (expects /path/to/cert.key to also exist)
  certificate = "/path/to/cert.crt"

Manual location

If you are using Prosody 0.9 or need to override the automatic location, you will need to provide the following config under the VirtualHost:

VirtualHost ""
  ssl = {
    certificate = "/etc/prosody/certs/";
    key = "/etc/prosody/certs/";

Reload Prosody (e.g. prosodyctl reload) to use the new certificate and key. In Prosody 0.9 you also need to reload mod_tls using one of the admin interfaces.

Note: If you received your certificate from a certificate authority, many require you to include an 'intermediate' certificate as well as yours. Simply add it into your certificate file, at the end. See certificate chains for more info. If your certificate came from Let's Encrypt, then fullchain.pem already contains this.

Automatic certificate import

From Prosody 0.10 prosodyctl gains the ability to import and activate certificates in one command:

prosodyctl --root cert import HOSTNAME /path/to/certificates

Certificates and their keys are copied to /etc/prosody/certs (can be changed with the certificates option) and then it signals Prosody to reload itself. --root lets prosodyctl write to paths that may not be writable by the prosody user, as is common with /etc/prosody. Multiple hostnames and paths can be given, as long as the hostnames are given before the paths.

This command can be put in cron or passed as a callback to automated certificate renewal programs such as certbot or other Let's Encrypt clients. For more information on using Prosody with these, see our Let's Encrypt page.


Certificate chains

Many certificate authorities provide you with an intermediate certificate which your server must supply to clients in addition to your own certificate so that they can verify it successfully.

The certbot (formerly "official") Let's Encrypt client includes the certificate and intermediate in the fullchain.pem file, so you should configure Prosody to use this as certificate.

ssl = {
  certificate = "/etc/letsencrypt/live/"; -- Note: Only readable by root by default
  key = "/etc/letsencrypt/live/";

Your CA should tell you if you need an intermediate certificate, and either send it to you or tell you where to download it from. Once you have it, you can simply add it to the end of your existing certificate file. The order is important, your own certificate must be at the top.

On the command-line, this is an easy way to append the intermediate (ICA) certificate to yours:

cat /path/to/ica.crt >> /path/to/prosody.crt

If you get them the wrong way round you might see this error when connecting with your client:

  info    Client disconnected: no shared cipher

Note: This error can also happen for other reasons, for example if your key file does not match your certificate, or the format of your certificate/key file is incorrect (they need to be in the standard PEM format).

Specify trusted certificate store

Most systems have a place to store all the certificates from CAs that they trust. By default Prosody uses the operating system's trusted certificate store (generally /etc/ssl/certs on Linux), but you can specify a different path with the capath option:

ssl = {
  -- (other SSL options here) --
  capath = "/usr/mycertstore";


Some SSL keys are protected with passphrases. If this is the case for your file then you can specify a 'password' field in the Prosody ssl config. For example:

    ssl = {
        key = "/path/to/key.key";
        certificate = "/path/to/certificate.crt";
        password = "youllneverguess";

However note that including your password in plain text in a config file can compromise your key if you're not careful and the passphrase is the only security measure. Always check that the permissions on both Prosody's config and the key itself are secure against untrusted users.

Should you want to remove the passphrase from a key entirely, you can run:

 cp server.key server.key.orig
 openssl rsa -in server.key.orig -out server.key

Again, be sure to check permissions!


Prosody's certificates and keys must be readable by the user that Prosody runs as. For security reasons it is recommended to make sure that no other user (except root) can read the key file.

These examples assume that Prosody is running as the prosody user (the default in most packages).

  sudo chmod 600 /path/to/certificate.key
  sudo chown prosody:prosody /path/to/certificate.key

Prosody should also be able to read the parent directories of the file.

To test that only Prosody can read the file:

  sudo -u prosody cat /path/to/certificate.key # Should succeed
  sudo -u nobody cat /path/to/certificate.key # Should fail

Server-to-server encryption issues

Openfire has a bug that causes the following errors in Prosody's logs:

  ssl handshake failed
  ssl handshake error: wrong version number

If you need to communicate with Openfire servers the only way currently is to disable server-to-server encryption. Apart from disabling encryption entirely, you can use a module to disable encryption for selected domains only - see mod_s2s_never_encrypt_blacklist.

Automatic location

Prosody 0.10+ will automatically search for a certificate and key for each host, unless a path is manually specified in the config file.

By default the directory that Prosody searches is the 'certs' subdirectory in the same location as the config file. You can override this with the global 'certificates' option:

   -- Global option only (won't work under a VirtualHost or Component):
   certificates = "/etc/prosody/certs"

Within this directory, these are the locations that Prosody will search:

Certificate file Key file
HOSTNAME/fullchain.pem HOSTNAME/privkey.pem

Service certificates

Certain Prosody services, such as 'legacy_ssl' and 'https', use a single certificate. These services also support automatic certificate discovery in Prosody 0.10. The same search list is used, but instead of the hostname, the name 'SERVICE_certificate' is used. For example, https_certificate.crt and https_certificate.key.

Alternatively the location can be manually overridden using the corresponding option in the config:

    https_certificate = "/path/to/cert.crt"

If you have the service running on multiple ports, you can serve a different certificate on each port:

    https_certificate = {
        [5281] = "/path/to/cert.crt";
        [6281] = "/path/to/different.crt";