# Nginx proxy: unknown directive "ssl\_early\_data"

**URL:** <https://forum.mattermost.com/t/nginx-proxy-unknown-directive-ssl-early-data/12112>\
**Category:** Troubleshooting\
**Created:** [August 25, 2021, 1:43pm UTC](https://forum.mattermost.com/t/nginx-proxy-unknown-directive-ssl-early-data/12112 "2021-08-25T13:43:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![pitininja](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/pitininja/32/5031_2.png) [@pitininja](https://forum.mattermost.com/u/pitininja)\
**Post date:** [August 25, 2021, 1:43pm UTC](https://forum.mattermost.com/t/nginx-proxy-unknown-directive-ssl-early-data/12112/1 "2021-08-25T13:43:43Z")

</div>

Hello good fellows of the Mattermost world.

**Summary**

I’m trying to setup a Nginx proxy with the example from the officiel documentation however when validating the Nginx configuration file it fails and throws `unknown directive "ssl_early_data"`.

TLS 1.3 is enabled on Nginx, and so is http\_ssl\_module.

**Steps to reproduce**

Install Mattermost, create Nginx configuration with example from [Installing Mattermost on Debian Buster — Mattermost documentation](https://docs.mattermost.com/install/install-debian.html#installing-nginx-server) then validate configuration file with `sudo nginx -t`.

**Expected behavior**

File is expected to be validated by Nginx.

**Observed behavior**

Error while validating Nginx configuration file:

```auto
nginx: [emerg] unknown directive "ssl_early_data" in /etc/nginx/sites-enabled/mattermost.conf:32
nginx: configuration file /etc/nginx/nginx.conf test failed

```

Thank you for any help I could get.

---

<div class="post-metadata">

**Author:** ![XxLilBoPeepsxX](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/xxlilbopeepsxx/32/4993_2.png) [@XxLilBoPeepsxX](https://forum.mattermost.com/u/XxLilBoPeepsxX)\
**Post date:** [August 30, 2021, 11:44am UTC](https://forum.mattermost.com/t/nginx-proxy-unknown-directive-ssl-early-data/12112/2 "2021-08-30T11:44:02Z")

</div>

Just did some quick researching - it seems that the module you are attempting to utilize takes advantage of TLS 1.3, which must be enabled/included in your configuration file explicitly, or else the `ssl_early_data` module will fail.

Example (without any of the reverse proxy configuration):

```auto
root@95eed784a081:/etc/nginx/conf.d# cat 443.conf

server {
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name _;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_early_data on;
        #
        ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
        ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
[..]

```

---

<div class="post-metadata">

**Author:** ![pitininja](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/pitininja/32/5031_2.png) [@pitininja](https://forum.mattermost.com/u/pitininja)\
**Post date:** [August 30, 2021, 12:01pm UTC](https://forum.mattermost.com/t/nginx-proxy-unknown-directive-ssl-early-data/12112/3 "2021-08-30T12:01:08Z")

</div>

Hello @XxLilBoPeepsxX,

Thank you for the suggestion.

The `TLSv1.3` instruction is already included in my Nginx configuration which is inspired from [the official Mattermost documentation](https://docs.mattermost.com/install/install-debian.html#installing-nginx-server).

It was already enabled by default in the main Nginx configuration anyway.

For more information here is my full configuration:

```nginx
upstream backend {
   server 127.0.0.1:8065;
   keepalive 32;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;

server {
  listen 80;
  server_name mattermost.xxxxxx.com;
  return 301 https://$server_name$request_uri;
}

server {
   listen 443 ssl http2;
   server_name mattermost.xxxxxx.com;

   http2_push_preload on; # Enable HTTP/2 Server Push

   ssl on;
   ssl_certificate /etc/letsencrypt/live/xxxxxx.com/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/xxxxxx.com/privkey.pem;
   ssl_session_timeout 1d;

   # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
   ssl_protocols TLSv1.2 TLSv1.3;

   # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
   # prevent replay attacks.
   #
   # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
   ssl_early_data on;

   ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
   ssl_prefer_server_ciphers on;
   ssl_session_cache shared:SSL:50m;
   # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
   add_header Strict-Transport-Security max-age=15768000;
   # OCSP Stapling ---
   # fetch OCSP records from URL in ssl_certificate and cache them
   ssl_stapling on;
   ssl_stapling_verify on;

   add_header X-Early-Data $tls1_3_early_data;

   location ~ /api/v[0-9]+/(users/)?websocket$ {
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
       client_max_body_size 50M;
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       client_body_timeout 60;
       send_timeout 300;
       lingering_timeout 5;
       proxy_connect_timeout 90;
       proxy_send_timeout 300;
       proxy_read_timeout 90s;
       proxy_http_version 1.1;
       proxy_pass http://backend;
   }

   location / {
       client_max_body_size 50M;
       proxy_set_header Connection "";
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       proxy_read_timeout 600s;
       proxy_cache mattermost_cache;
       proxy_cache_revalidate on;
       proxy_cache_min_uses 2;
       proxy_cache_use_stale timeout;
       proxy_cache_lock on;
       proxy_http_version 1.1;
       proxy_pass http://backend;
   }
}

# This block is useful for debugging TLS v1.3. Please feel free to remove this
# and use the `$ssl_early_data` variable exposed by NGINX directly should you
# wish to do so.
map $ssl_early_data $tls1_3_early_data {
  "~." $ssl_early_data;
  default "";
}

```

Regards sir

---

<div class="post-metadata">

**Author:** ![XxLilBoPeepsxX](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/xxlilbopeepsxx/32/4993_2.png) [@XxLilBoPeepsxX](https://forum.mattermost.com/u/XxLilBoPeepsxX)\
**Post date:** [September 2, 2021, 2:05pm UTC](https://forum.mattermost.com/t/nginx-proxy-unknown-directive-ssl-early-data/12112/4 "2021-09-02T14:05:09Z")

</div>

I see, thank you for providing that information - would you be able to send the contents of the `/etc/nginx/mods-available/` folder? I’m curious if the Nginx module that uses this function is installed or not.

---

<div class="post-metadata">

**Author:** ![pitininja](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/pitininja/32/5031_2.png) [@pitininja](https://forum.mattermost.com/u/pitininja)\
**Post date:** [September 2, 2021, 2:35pm UTC](https://forum.mattermost.com/t/nginx-proxy-unknown-directive-ssl-early-data/12112/5 "2021-09-02T14:35:21Z")

</div>

Hello sir,

`/etc/nginx/modules-available/` is empty, however:

`/usr/share/nginx/modules-available/` contains

```auto
mod-http-auth-pam.conf
mod-http-echo.conf
mod-http-image-filter.conf
mod-http-upstream-fair.conf
mod-mail.conf
mod-http-dav-ext.conf
mod-http-geoip.conf
mod-http-subs-filter.conf
mod-http-xslt-filter.conf
mod-stream.conf

```

and `/etc/nginx/modules-enabled/` contains

```auto
50-mod-http-auth-pam.conf -> /usr/share/nginx/modules-available/mod-http-auth-pam.conf
50-mod-http-dav-ext.conf -> /usr/share/nginx/modules-available/mod-http-dav-ext.conf
50-mod-http-echo.conf -> /usr/share/nginx/modules-available/mod-http-echo.conf
50-mod-http-geoip.conf -> /usr/share/nginx/modules-available/mod-http-geoip.conf
50-mod-http-image-filter.conf -> /usr/share/nginx/modules-available/mod-http-image-filter.conf
50-mod-http-subs-filter.conf -> /usr/share/nginx/modules-available/mod-http-subs-filter.conf
50-mod-http-upstream-fair.conf -> /usr/share/nginx/modules-available/mod-http-upstream-fair.conf
50-mod-http-xslt-filter.conf -> /usr/share/nginx/modules-available/mod-http-xslt-filter.conf
50-mod-mail.conf -> /usr/share/nginx/modules-available/mod-mail.conf
50-mod-stream.conf -> /usr/share/nginx/modules-available/mod-stream.conf

```

I don’t see anything related to `http_ssl_module` in here. Does that mean it’s not installed?

I thought it was because when I do `sudo nginx -V` I got

```auto
nginx version: nginx/1.14.2
built with OpenSSL 1.1.1d 10 Sep 2019
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-m1Thpq/nginx-1.14.2=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-m1Thpq/nginx-1.14.2/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-m1Thpq/nginx-1.14.2/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-m1Thpq/nginx-1.14.2/debian/modules/http-echo --add-dynamic-module=/build/nginx-m1Thpq/nginx-1.14.2/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-m1Thpq/nginx-1.14.2/debian/modules/http-subs-filter

```

which contains `--with-http_ssl_module`.

Regards sir

---

<div class="post-metadata">

**Author:** ![kowalski-relent](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/kowalski-relent/32/5973_2.png) [@kowalski-relent](https://forum.mattermost.com/u/kowalski-relent)\
**Post date:** [October 11, 2022, 1:32pm UTC](https://forum.mattermost.com/t/nginx-proxy-unknown-directive-ssl-early-data/12112/6 "2022-10-11T13:32:07Z")

</div>

You can update your nginx to 1.15 or later version, see [official doc](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data), the directive appeared in version 1.15.3.
