Skip to content

Last updated: 2026-05-14

NATS TLS Configuration

NATS is written in Go and uses Go's TLS stack, so cipher suite names follow Go's naming convention rather than OpenSSL's. The nats-server.conf format is NATS's own configuration language (similar to nginx config blocks).

NATS has three independent TLS surfaces: client connections, cluster peer connections, and leaf node connections. Each gets its own tls block.

Client TLS

Add a tls block at the top level of nats-server.conf:

tls {
    cert_file:   "/etc/nats/ssl/server.crt"
    key_file:    "/etc/nats/ssl/server.key"
    ca_file:     "/etc/nats/ssl/ca.crt"
    verify:      true
    min_version: "1.2"

    cipher_suites: [
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
        "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
    ]

    curve_preferences: [
        "X25519",
        "CurveP256",
        "CurveP384"
    ]
}

Key settings:

If any client supports TLS 1.3, Go will negotiate it regardless of cipher_suites. Set min_version: "1.3" to enforce TLS 1.3 exclusively, only viable if all clients support it.

Cluster TLS

For peer-to-peer connections within a NATS cluster, add a tls block inside the cluster block:

cluster {
    name: my-cluster
    port: 6222

    tls {
        cert_file:   "/etc/nats/ssl/server.crt"
        key_file:    "/etc/nats/ssl/server.key"
        ca_file:     "/etc/nats/ssl/ca.crt"
        verify:      true
        min_version: "1.2"
    }

    routes: [
        nats-route://nats1.internal:6222
        nats-route://nats2.internal:6222
        nats-route://nats3.internal:6222
    ]
}

With verify: true in the cluster block, each node must present a valid certificate, preventing unauthorized nodes from joining as cluster members.

Leaf Node TLS

For leaf nodes (extending a cluster across network or security boundaries):

leafnodes {
    port: 7422

    tls {
        cert_file:   "/etc/nats/ssl/server.crt"
        key_file:    "/etc/nats/ssl/server.key"
        ca_file:     "/etc/nats/ssl/ca.crt"
        verify:      true
        min_version: "1.2"
    }
}

Client Connections

nats CLI

nats --server tls://nats.example.com:4222 \
     --tlscert /etc/nats/ssl/client.crt \
     --tlskey /etc/nats/ssl/client.key \
     --tlsca /etc/nats/ssl/ca.crt \
     sub "my.subject"

Use the tls:// scheme in the server URL to require TLS. The nats:// scheme with TLS options will also negotiate TLS, but tls:// makes the requirement explicit.

Verification

Test the TLS handshake:

openssl s_client -connect nats.example.com:4222 -CAfile /etc/nats/ssl/ca.crt

After a successful handshake, NATS sends an INFO banner with server metadata. If TLS is required and a client connects without it, the server sends an error and closes the connection immediately.

Enable debug logging in nats-server.conf to trace TLS negotiation:

debug: true
trace: true

Related Guides

View all Message Brokers guides →

Configured TLS? Now Monitor It.

Generator Labs alerts you before certificates expire, get revoked, or fail chain validation — across HTTPS, SMTPS, IMAPS, LDAPS, and more.

Certificate Monitoring →