Configure TLS
Valkey GLIDE supports secure TLS connections to a data store.
It’s important to note that TLS support in Valkey GLIDE relies on rustls. Currently, Valkey GLIDE employs the default rustls settings with no option for customization.
Enabling TLS Connections
Section titled “Enabling TLS Connections”Enabling TLS is as simple as setting use_tls=True in your configuration. The client will use your system’s default certificate trust store to verify the server.
Cluster Mode
Section titled “Cluster Mode”from glide import ( GlideClusterClient, GlideClusterClientConfiguration, NodeAddress)
addresses = [NodeAddress(host="address.example.com", port=6379)]client_config = GlideClusterClientConfiguration(addresses, use_tls=True)
client = await GlideClusterClient.create(client_config)import glide.api.GlideClusterClient;import glide.api.models.configuration.GlideClusterClientConfiguration;import glide.api.models.configuration.NodeAddress;
GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder() .host("address.example.com") .port(6379) .build()) .useTLS(true) .build();
GlideClusterClient client = GlideClusterClient.createClient(config).get();import {GlideClusterClient} from "@valkey/valkey-glide";
const addresses = [ { host: "address.example.com", port: 6379 }];
const client = await GlideClusterClient.createClient({ addresses: addresses, useTLS: true});import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectClusterWithTLS() error { clientConfig := config.NewClusterClientConfiguration(). WithAddress(&config.NodeAddress{Host: "address.example.com", Port: 6379}). WithUseTLS(true)
client, err := glide.NewClusterClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}using Valkey.Glide;using static Valkey.Glide.ConnectionConfiguration;
var config = new ClusterClientConfigurationBuilder() .WithAddress("address.example.com", 6379) .WithTls() .Build();
await using var client = await GlideClusterClient.CreateClient(config);$addresses = [ ['host' => 'address.example.com', 'port' => 6379]];
$client = new ValkeyGlideCluster( addresses: $addresses, use_tls: true);require "valkey"
nodes = [{ host: "address.example.com", port: 6379 }]
client = Valkey.new(nodes: nodes, cluster_mode: true, ssl: true)Standalone
Section titled “Standalone”from glide import ( GlideClient, GlideClientConfiguration, NodeAddress)
addresses = [ NodeAddress(host="primary.example.com", port=6379), NodeAddress(host="replica1.example.com", port=6379), NodeAddress(host="replica2.example.com", port=6379) ]client_config = GlideClientConfiguration(addresses, use_tls=True)
client = await GlideClient.create(client_config)import glide.api.GlideClient;import glide.api.models.configuration.GlideClientConfiguration;import glide.api.models.configuration.NodeAddress;
GlideClientConfiguration config = GlideClientConfiguration.builder() .address(NodeAddress.builder() .host("primary.example.com") .port(6379) .build()) .useTLS(true) .build();
GlideClient client = GlideClient.createClient(config).get();import {GlideClient} from "@valkey/valkey-glide";
const addresses = [ { host: "address.example.com", port: 6379 }];
const client = await GlideClient.createClient({ addresses: addresses, useTLS: true});import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectStandaloneWithTLS() error { clientConfig := config.NewClientConfiguration(). WithAddress(&config.NodeAddress{Host: "primary.example.com", Port: 6379}). WithUseTLS(true)
client, err := glide.NewClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}using Valkey.Glide;using static Valkey.Glide.ConnectionConfiguration;
var config = new StandaloneClientConfigurationBuilder() .WithAddress("primary.example.com", 6379) .WithAddress("replica1.example.com", 6379) .WithAddress("replica2.example.com", 6379) .WithTls() .Build();
await using var client = await GlideClient.CreateClient(config);$addresses = [ ['host' => 'primary.example.com', 'port' => 6379], ['host' => 'replica1.example.com', 'port' => 6379], ['host' => 'replica2.example.com', 'port' => 6379]];
$client = new ValkeyGlide();$client->connect(addresses: $addresses, use_tls: true);require "valkey"
client = Valkey.new(host: "primary.example.com", port: 6379, ssl: true)A rediss:// URL enables TLS as well:
client = Valkey.new(url: "rediss://primary.example.com:6379")Advanced TLS Configurations
Section titled “Advanced TLS Configurations”Insecure TLS Mode
Section titled “Insecure TLS Mode”Insecure TLS mode bypasses certificate verification. This is useful when connecting to servers using self-signed certificates or when DNS entries don’t match certificate hostnames.
Cluster Mode
Section titled “Cluster Mode”from glide import ( AdvancedGlideClusterClientConfiguration, GlideClusterClient, GlideClusterClientConfiguration, NodeAddress, TlsAdvancedConfiguration,)
tls_config = TlsAdvancedConfiguration(use_insecure_tls=True)
advanced_config = AdvancedGlideClusterClientConfiguration(tls_config=tls_config)
client_config = GlideClusterClientConfiguration( addresses=[NodeAddress(host="address.example.com", port=6379)], use_tls=True, advanced_config=advanced_config,)
client = await GlideClusterClient.create(client_config)import glide.api.GlideClusterClient;import glide.api.models.configuration.AdvancedGlideClusterClientConfiguration;import glide.api.models.configuration.GlideClusterClientConfiguration;import glide.api.models.configuration.NodeAddress;import glide.api.models.configuration.TlsAdvancedConfiguration;
TlsAdvancedConfiguration tlsConfig = TlsAdvancedConfiguration.builder() .useInsecureTLS(true) .build();
AdvancedGlideClusterClientConfiguration advancedConfig = AdvancedGlideClusterClientConfiguration.builder() .tlsAdvancedConfiguration(tlsConfig) .build();
GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder().host("address.example.com").port(6379).build()) .useTLS(true) .advancedConfiguration(advancedConfig) .build();
GlideClusterClient client = GlideClusterClient.createClient(config).get();import { GlideClusterClient } from "@valkey/valkey-glide";
const client = await GlideClusterClient.createClient({ addresses: [{ host: "address.example.com", port: 6379 }], useTLS: true, advancedConfiguration: { tlsAdvancedConfiguration: { insecure: true }, },});import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectClusterWithInsecureTLS() error { tlsConfig := config.NewTlsConfiguration().WithInsecureTLS(true)
advancedConfig := config.NewAdvancedClusterClientConfiguration(). WithTlsConfiguration(tlsConfig)
clientConfig := config.NewClusterClientConfiguration(). WithAddress(&config.NodeAddress{Host: "address.example.com", Port: 6379}). WithUseTLS(true). WithAdvancedConfiguration(advancedConfig)
client, err := glide.NewClusterClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}using Valkey.Glide;using static Valkey.Glide.ConnectionConfiguration;
var config = new ClusterClientConfigurationBuilder() .WithAddress("address.example.com", 6379) .WithTls() .WithInsecureTls() .Build();
await using var client = await GlideClusterClient.CreateClient(config);$client = new ValkeyGlideCluster( addresses: [['host' => 'address.example.com', 'port' => 6379]], use_tls: true, advanced_config: ['tls_config' => ['use_insecure_tls' => true]]);Standalone
Section titled “Standalone”from glide import ( AdvancedGlideClientConfiguration, GlideClient, GlideClientConfiguration, NodeAddress, TlsAdvancedConfiguration,)
tls_config = TlsAdvancedConfiguration(use_insecure_tls=True)
advanced_config = AdvancedGlideClientConfiguration(tls_config=tls_config)
client_config = GlideClientConfiguration( addresses=[NodeAddress(host="primary.example.com", port=6379)], use_tls=True, advanced_config=advanced_config,)
client = await GlideClient.create(client_config)import glide.api.GlideClient;import glide.api.models.configuration.AdvancedGlideClientConfiguration;import glide.api.models.configuration.GlideClientConfiguration;import glide.api.models.configuration.NodeAddress;import glide.api.models.configuration.TlsAdvancedConfiguration;
TlsAdvancedConfiguration tlsConfig = TlsAdvancedConfiguration.builder() .useInsecureTLS(true) .build();
AdvancedGlideClientConfiguration advancedConfig = AdvancedGlideClientConfiguration.builder() .tlsAdvancedConfiguration(tlsConfig) .build();
GlideClientConfiguration config = GlideClientConfiguration.builder() .address(NodeAddress.builder().host("primary.example.com").port(6379).build()) .useTLS(true) .advancedConfiguration(advancedConfig) .build();
GlideClient client = GlideClient.createClient(config).get();import { GlideClient } from "@valkey/valkey-glide";
const client = await GlideClient.createClient({ addresses: [{ host: "primary.example.com", port: 6379 }], useTLS: true, advancedConfiguration: { tlsAdvancedConfiguration: { insecure: true }, },});import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectStandaloneWithInsecureTLS() error { tlsConfig := config.NewTlsConfiguration().WithInsecureTLS(true)
advancedConfig := config.NewAdvancedClientConfiguration(). WithTlsConfiguration(tlsConfig)
clientConfig := config.NewClientConfiguration(). WithAddress(&config.NodeAddress{Host: "primary.example.com", Port: 6379}). WithUseTLS(true). WithAdvancedConfiguration(advancedConfig)
client, err := glide.NewClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}using Valkey.Glide;using static Valkey.Glide.ConnectionConfiguration;
var config = new StandaloneClientConfigurationBuilder() .WithAddress("primary.example.com", 6379) .WithTls() .WithInsecureTls() .Build();
await using var client = await GlideClient.CreateClient(config);$client = new ValkeyGlide();$client->connect( addresses: [['host' => 'primary.example.com', 'port' => 6379]], use_tls: true, advanced_config: ['tls_config' => ['use_insecure_tls' => true]]);Custom Root Certificates
Section titled “Custom Root Certificates”You can provide custom root certificates for TLS connections. This is useful when connecting to servers with self-signed certificates or corporate certificate authorities.
Certificate Behavior:
- If
root_pem_cacertsisNone(default), the system’s default certificate trust store is used - If
root_pem_cacertsis an empty bytes object, an error will be returned - Certificates must be in PEM format as a bytes object
- Multiple certificates can be provided by concatenating them in PEM format
Example - Connecting with Custom Root Certificate from File
Section titled “Example - Connecting with Custom Root Certificate from File”from glide import ( GlideClusterClient, GlideClusterClientConfiguration, NodeAddress, TlsAdvancedConfiguration, AdvancedGlideClusterClientConfiguration)
# Read certificate filewith open("/path/to/ca-cert.pem", "rb") as f: root_cert = f.read()
tls_config = TlsAdvancedConfiguration(root_pem_cacerts=root_cert)
advanced_config = AdvancedGlideClusterClientConfiguration( tls_config=tls_config)
addresses = [NodeAddress(host="address.example.com", port=6379)]client_config = GlideClusterClientConfiguration( addresses, use_tls=True, advanced_config=advanced_config)
client = await GlideClusterClient.create(client_config)Example - Using Certificate as Bytes
Section titled “Example - Using Certificate as Bytes”from glide import ( GlideClient, GlideClientConfiguration, NodeAddress, TlsAdvancedConfiguration, AdvancedGlideClientConfiguration)
cert_data = b"""-----BEGIN CERTIFICATE-----MIIDXTCCAkWgAwIBAgIJAKL0UG+mRKmzMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV...-----END CERTIFICATE-----"""
tls_config = TlsAdvancedConfiguration(root_pem_cacerts=cert_data)
advanced_config = AdvancedGlideClientConfiguration( tls_config=tls_config)
addresses = [NodeAddress(host="primary.example.com", port=6379)]client_config = GlideClientConfiguration( addresses, use_tls=True, advanced_config=advanced_config)
client = await GlideClient.create(client_config)Example - Multiple Certificates (Certificate Chain)
Section titled “Example - Multiple Certificates (Certificate Chain)”from glide import ( GlideClusterClient, GlideClusterClientConfiguration, NodeAddress, TlsAdvancedConfiguration, AdvancedGlideClusterClientConfiguration)
# Read multiple certificate fileswith open("/path/to/cert1.pem", "rb") as f: cert1 = f.read()with open("/path/to/cert2.pem", "rb") as f: cert2 = f.read()with open("/path/to/cert3.pem", "rb") as f: cert3 = f.read()
# Concatenate certificatescombined_certs = cert1 + cert2 + cert3
tls_config = TlsAdvancedConfiguration(root_pem_cacerts=combined_certs)
advanced_config = AdvancedGlideClusterClientConfiguration( tls_config=tls_config)
addresses = [NodeAddress(host="address.example.com", port=6379)]client_config = GlideClusterClientConfiguration( addresses, use_tls=True, advanced_config=advanced_config)
client = await GlideClusterClient.create(client_config)Certificate Behavior:
- If
rootCertificatesis not set (default), the system’s default certificate trust store is used - If
rootCertificatesis an empty byte array, an error will be returned - Certificates must be in PEM format as a byte array
- Multiple certificates can be provided by concatenating them in PEM format
Example - Connecting with Custom Root Certificate from File
Section titled “Example - Connecting with Custom Root Certificate from File”import glide.api.GlideClusterClient;import glide.api.models.configuration.AdvancedGlideClusterClientConfiguration;import glide.api.models.configuration.GlideClusterClientConfiguration;import glide.api.models.configuration.NodeAddress;import glide.api.models.configuration.TlsAdvancedConfiguration;
import java.nio.file.Files;import java.nio.file.Paths;
byte[] rootCaBytes = Files.readAllBytes(Paths.get("/path/to/ca-cert.pem"));
TlsAdvancedConfiguration tlsConfig = TlsAdvancedConfiguration.builder() .rootCertificates(rootCaBytes) .build();
AdvancedGlideClusterClientConfiguration advancedConfig = AdvancedGlideClusterClientConfiguration.builder() .tlsAdvancedConfiguration(tlsConfig) .build();
GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder().host("address.example.com").port(6379).build()) .useTLS(true) .advancedConfiguration(advancedConfig) .build();
GlideClusterClient client = GlideClusterClient.createClient(config).get();Example - Connecting with Custom Root Certificates from KeyStore
Section titled “Example - Connecting with Custom Root Certificates from KeyStore”TlsAdvancedConfiguration.fromKeyStore is a static factory that pulls trusted certificate entries out of a Java KeyStore (JKS or PKCS12) and returns a fully-configured TlsAdvancedConfiguration.
import glide.api.GlideClusterClient;import glide.api.models.configuration.AdvancedGlideClusterClientConfiguration;import glide.api.models.configuration.GlideClusterClientConfiguration;import glide.api.models.configuration.NodeAddress;import glide.api.models.configuration.TlsAdvancedConfiguration;
TlsAdvancedConfiguration tlsConfig = TlsAdvancedConfiguration.fromKeyStore( "/path/to/truststore.p12", "changeit".toCharArray(), "PKCS12");
AdvancedGlideClusterClientConfiguration advancedConfig = AdvancedGlideClusterClientConfiguration.builder() .tlsAdvancedConfiguration(tlsConfig) .build();
GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder().host("address.example.com").port(6379).build()) .useTLS(true) .advancedConfiguration(advancedConfig) .build();
GlideClusterClient client = GlideClusterClient.createClient(config).get();Certificate Behavior:
- If
rootCertificatesis not set (default), the system’s default certificate trust store is used - If
rootCertificatesis empty, an error will be returned - Certificates must be in PEM format, provided as a
Bufferor a raw PEMstring - Multiple certificates can be provided by concatenating them in PEM format
Example - Connecting with Custom Root Certificate from File
Section titled “Example - Connecting with Custom Root Certificate from File”import { readFileSync } from "node:fs";import { GlideClusterClient } from "@valkey/valkey-glide";
const rootCertificates = readFileSync("/path/to/ca-cert.pem");
const client = await GlideClusterClient.createClient({ addresses: [{ host: "address.example.com", port: 6379 }], useTLS: true, advancedConfiguration: { tlsAdvancedConfiguration: { rootCertificates }, },});Certificate Behavior:
- If
WithRootCertificatesis not called (default), the system’s default certificate trust store is used - Certificates must be in PEM format as a byte slice
- Multiple certificates can be provided by concatenating them in PEM format
config.LoadRootCertificatesFromFilereads a PEM file and returns the bytes, ready to pass toWithRootCertificates
Example - Connecting with Custom Root Certificate from File
Section titled “Example - Connecting with Custom Root Certificate from File”import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectClusterWithCustomRootCA() error { rootCerts, err := config.LoadRootCertificatesFromFile("/path/to/ca-cert.pem") if err != nil { return err }
tlsConfig := config.NewTlsConfiguration().WithRootCertificates(rootCerts)
advancedConfig := config.NewAdvancedClusterClientConfiguration(). WithTlsConfiguration(tlsConfig)
clientConfig := config.NewClusterClientConfiguration(). WithAddress(&config.NodeAddress{Host: "address.example.com", Port: 6379}). WithUseTLS(true). WithAdvancedConfiguration(advancedConfig)
client, err := glide.NewClusterClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}Certificate Behavior:
- If no trusted certificates are provided, the system’s default certificate trust store is used.
- Empty certificate data will throw an
ArgumentException. - Certificate data exceeding 10 MB will throw an
ArgumentException - Multiple certificates can be added by calling
WithTrustedCertificatemultiple times
Example - Connecting with Custom Root Certificate from File
Section titled “Example - Connecting with Custom Root Certificate from File”using Valkey.Glide;using static Valkey.Glide.ConnectionConfiguration;
var config = new ClusterClientConfigurationBuilder() .WithAddress("address.example.com", 6379) .WithTls() .WithTrustedCertificate("/path/to/ca-cert.pem") .Build();
await using var client = await GlideClusterClient.CreateClient(config);Example - Using Certificate as Bytes
Section titled “Example - Using Certificate as Bytes”using System.Text;using Valkey.Glide;using static Valkey.Glide.ConnectionConfiguration;
var certData = Encoding.UTF8.GetBytes( "-----BEGIN CERTIFICATE-----\n" + "MIIDXTCCAkWgAwIBAgIJAKL0UG+mRKmzMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n" + "...\n" + "-----END CERTIFICATE-----\n");
var config = new StandaloneClientConfigurationBuilder() .WithTls() .WithTrustedCertificate(certData) .Build();
await using var client = await GlideClient.CreateClient(config);Example - Multiple Certificates (Certificate Chain)
Section titled “Example - Multiple Certificates (Certificate Chain)”using Valkey.Glide;using static Valkey.Glide.ConnectionConfiguration;
var config = new ClusterClientConfigurationBuilder() .WithAddress("address.example.com", 6379) .WithTls() .WithTrustedCertificate("/path/to/cert1.pem") .WithTrustedCertificate("/path/to/cert2.pem") .WithTrustedCertificate("/path/to/cert3.pem") .Build();
await using var client = await GlideClusterClient.CreateClient(config);Example - Connecting with Custom Root Certificate
Section titled “Example - Connecting with Custom Root Certificate”// Read certificate file$rootCert = file_get_contents('/path/to/ca-cert.pem');
$client = new ValkeyGlide();$client->connect( addresses: [['host' => 'address.example.com', 'port' => 6379]], use_tls: true, advanced_config: ['tls_config' => ['root_certs' => $rootCert]]);Example - Using Certificate as String
Section titled “Example - Using Certificate as String”$certData = <<<'CERT'-----BEGIN CERTIFICATE-----MIIDXTCCAkWgAwIBAgIJAKL0UG+mRKmzMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV...-----END CERTIFICATE-----CERT;
$client = new ValkeyGlideCluster( addresses: [['host' => 'address.example.com', 'port' => 6379]], use_tls: true, advanced_config: ['tls_config' => ['root_certs' => $certData]]);Certificate Behavior:
- If
ssl_paramsis not provided, the system’s default certificate trust store is used ca_filetakes a path to a CA certificate file in PEM format- Multiple certificates can be provided as PEM strings via the
root_certsarray, or by pointingca_pathat a directory of.crt/.pemfiles
Example - Connecting with Custom Root Certificate from File
Section titled “Example - Connecting with Custom Root Certificate from File”require "valkey"
client = Valkey.new( host: "address.example.com", port: 6379, ssl: true, ssl_params: { ca_file: "/path/to/ca-cert.pem" })Example - Using Certificate as String
Section titled “Example - Using Certificate as String”cert_data = <<~CERT -----BEGIN CERTIFICATE----- MIIDXTCCAkWgAwIBAgIJAKL0UG+mRKmzMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV ... -----END CERTIFICATE-----CERT
client = Valkey.new( host: "address.example.com", port: 6379, ssl: true, ssl_params: { root_certs: [cert_data] })Example - Client Certificate (Mutual TLS)
Section titled “Example - Client Certificate (Mutual TLS)”client = Valkey.new( host: "address.example.com", port: 6379, ssl: true, ssl_params: { ca_file: "/path/to/ca-cert.pem", cert: "/path/to/client-cert.pem", key: "/path/to/client-key.pem" })Mutual TLS (mTLS)
Section titled “Mutual TLS (mTLS)”Mutual TLS has the client present its own certificate and private key to the server, so the server can authenticate the client in addition to the client authenticating the server. GLIDE supports three mTLS modes: in-memory PEM bytes (loaded once), path-based with automatic reload at the core’s default cadence, and path-based with a custom reload interval.
mTLS still requires TLS to be enabled on the top-level client configuration (use_tls=True in Python, .useTLS(true) in Java, useTLS: true in Node.js, .WithUseTLS(true) in Go).
The advanced TLS configuration only supplies the client-side material; it does not enable TLS on its own.
Reload behavior applies to path-based modes only. The GLIDE core reads the certificate and key from disk at connect time and re-reads them on a schedule so a rotated certificate is picked up on the next reconnect. Open connections keep their current material. If a reload fails (missing file, mismatched key, unreadable), the last known-good material is kept until a subsequent read succeeds. Byte-based mTLS is inherently static: the material is read once at connect time and does not reload.
Path-based and byte-based mTLS are mutually exclusive within a single configuration. Supplying both is rejected at configuration time in every SDK.
A custom reload interval must be a positive whole number of seconds no greater than 4,294,967,295 (the maximum value of an unsigned 32-bit integer, roughly 136 years). Sub-second, zero, negative, and oversized values are rejected at configuration time.
In-memory PEM (static)
Section titled “In-memory PEM (static)”Use the byte-based entry point when the client certificate and key are already loaded as PEM bytes (for example, fetched from a secret store). The material is read once at connect time and does not reload.
from glide import ( AdvancedGlideClusterClientConfiguration, GlideClusterClient, GlideClusterClientConfiguration, NodeAddress, TlsAdvancedConfiguration,)
# Load PEM bytes from a secret store, not from source.client_cert: bytes = ...client_key: bytes = ...
tls_config = TlsAdvancedConfiguration( client_cert_pem=client_cert, client_key_pem=client_key,)
advanced_config = AdvancedGlideClusterClientConfiguration(tls_config=tls_config)
client_config = GlideClusterClientConfiguration( addresses=[NodeAddress(host="address.example.com", port=6379)], use_tls=True, advanced_config=advanced_config,)
client = await GlideClusterClient.create(client_config)import glide.api.GlideClusterClient;import glide.api.models.configuration.AdvancedGlideClusterClientConfiguration;import glide.api.models.configuration.GlideClusterClientConfiguration;import glide.api.models.configuration.NodeAddress;import glide.api.models.configuration.TlsAdvancedConfiguration;
// Replace loadPemFromSecretStore(...) with your own secret-store lookup returning PEM-encoded bytes.byte[] clientCert = loadPemFromSecretStore("client-cert");byte[] clientKey = loadPemFromSecretStore("client-key");
TlsAdvancedConfiguration tlsConfig = TlsAdvancedConfiguration.builder() .useMutualTls(clientCert, clientKey) .build();
AdvancedGlideClusterClientConfiguration advancedConfig = AdvancedGlideClusterClientConfiguration.builder() .tlsAdvancedConfiguration(tlsConfig) .build();
GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder().host("address.example.com").port(6379).build()) .useTLS(true) .advancedConfiguration(advancedConfig) .build();
GlideClusterClient client = GlideClusterClient.createClient(config).get();import { GlideClusterClient, MutualTls } from "@valkey/valkey-glide";
// Load PEM bytes from a secret store, not from source.// Replace loadPemFromSecretStore(...) with your own secret-store lookup returning PEM-encoded bytes.const clientCertificate: Buffer = loadPemFromSecretStore("client-cert");const clientKey: Buffer = loadPemFromSecretStore("client-key");
const mutualTls: MutualTls = { kind: "bytes", clientCertificate, clientKey,};
const client = await GlideClusterClient.createClient({ addresses: [{ host: "address.example.com", port: 6379 }], useTLS: true, advancedConfiguration: { tlsAdvancedConfiguration: { mutualTls }, },});import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectClusterWithMutualTLSBytes() error { // Replace loadPemFromSecretStore(...) with your own secret-store lookup returning PEM-encoded bytes. clientCert, clientKey := loadPemFromSecretStore()
tlsConfig, err := config.NewTlsConfiguration().WithMutualTLS(clientCert, clientKey) if err != nil { return err }
advancedConfig := config.NewAdvancedClusterClientConfiguration(). WithTlsConfiguration(tlsConfig)
clientConfig := config.NewClusterClientConfiguration(). WithAddress(&config.NodeAddress{Host: "address.example.com", Port: 6379}). WithUseTLS(true). WithAdvancedConfiguration(advancedConfig)
client, err := glide.NewClusterClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}Path-based with automatic reload
Section titled “Path-based with automatic reload”Point at PEM files on disk and let the core reload them at its default cadence. Rotated material is picked up on the next reconnect after a successful reload.
from glide import ( AdvancedGlideClusterClientConfiguration, GlideClusterClient, GlideClusterClientConfiguration, NodeAddress, TlsAdvancedConfiguration,)
tls_config = TlsAdvancedConfiguration( client_cert_path="/etc/glide/client.pem", client_key_path="/etc/glide/client.key",)
advanced_config = AdvancedGlideClusterClientConfiguration(tls_config=tls_config)
client_config = GlideClusterClientConfiguration( addresses=[NodeAddress(host="address.example.com", port=6379)], use_tls=True, advanced_config=advanced_config,)
client = await GlideClusterClient.create(client_config)import glide.api.GlideClusterClient;import glide.api.models.configuration.AdvancedGlideClusterClientConfiguration;import glide.api.models.configuration.GlideClusterClientConfiguration;import glide.api.models.configuration.NodeAddress;import glide.api.models.configuration.TlsAdvancedConfiguration;
TlsAdvancedConfiguration tlsConfig = TlsAdvancedConfiguration.builder() .useMutualTlsWithReload("/etc/glide/client.pem", "/etc/glide/client.key") .build();
AdvancedGlideClusterClientConfiguration advancedConfig = AdvancedGlideClusterClientConfiguration.builder() .tlsAdvancedConfiguration(tlsConfig) .build();
GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder().host("address.example.com").port(6379).build()) .useTLS(true) .advancedConfiguration(advancedConfig) .build();
GlideClusterClient client = GlideClusterClient.createClient(config).get();import { GlideClusterClient, MutualTls } from "@valkey/valkey-glide";
const mutualTls: MutualTls = { kind: "path", clientCertPath: "/etc/glide/client.pem", clientKeyPath: "/etc/glide/client.key",};
const client = await GlideClusterClient.createClient({ addresses: [{ host: "address.example.com", port: 6379 }], useTLS: true, advancedConfiguration: { tlsAdvancedConfiguration: { mutualTls }, },});import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectClusterWithMutualTLSFromFiles() error { tlsConfig, err := config.NewTlsConfiguration().WithMutualTLSFromFiles( "/etc/glide/client.pem", "/etc/glide/client.key", ) if err != nil { return err }
advancedConfig := config.NewAdvancedClusterClientConfiguration(). WithTlsConfiguration(tlsConfig)
clientConfig := config.NewClusterClientConfiguration(). WithAddress(&config.NodeAddress{Host: "address.example.com", Port: 6379}). WithUseTLS(true). WithAdvancedConfiguration(advancedConfig)
client, err := glide.NewClusterClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}Path-based with a custom reload interval
Section titled “Path-based with a custom reload interval”Pass a positive whole number of seconds to override the core default cadence.
from glide import ( AdvancedGlideClusterClientConfiguration, GlideClusterClient, GlideClusterClientConfiguration, NodeAddress, TlsAdvancedConfiguration,)
tls_config = TlsAdvancedConfiguration( client_cert_path="/etc/glide/client.pem", client_key_path="/etc/glide/client.key", cert_reload_interval_seconds=60,)
advanced_config = AdvancedGlideClusterClientConfiguration(tls_config=tls_config)
client_config = GlideClusterClientConfiguration( addresses=[NodeAddress(host="address.example.com", port=6379)], use_tls=True, advanced_config=advanced_config,)
client = await GlideClusterClient.create(client_config)import glide.api.GlideClusterClient;import glide.api.models.configuration.AdvancedGlideClusterClientConfiguration;import glide.api.models.configuration.GlideClusterClientConfiguration;import glide.api.models.configuration.NodeAddress;import glide.api.models.configuration.TlsAdvancedConfiguration;
TlsAdvancedConfiguration tlsConfig = TlsAdvancedConfiguration.builder() .useMutualTlsWithReload("/etc/glide/client.pem", "/etc/glide/client.key", 60) .build();
AdvancedGlideClusterClientConfiguration advancedConfig = AdvancedGlideClusterClientConfiguration.builder() .tlsAdvancedConfiguration(tlsConfig) .build();
GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder().host("address.example.com").port(6379).build()) .useTLS(true) .advancedConfiguration(advancedConfig) .build();
GlideClusterClient client = GlideClusterClient.createClient(config).get();import { GlideClusterClient, MutualTls } from "@valkey/valkey-glide";
const mutualTls: MutualTls = { kind: "path", clientCertPath: "/etc/glide/client.pem", clientKeyPath: "/etc/glide/client.key", reloadIntervalSeconds: 60,};
const client = await GlideClusterClient.createClient({ addresses: [{ host: "address.example.com", port: 6379 }], useTLS: true, advancedConfiguration: { tlsAdvancedConfiguration: { mutualTls }, },});import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectClusterWithMutualTLSCustomInterval() error { tlsConfig, err := config.NewTlsConfiguration().WithMutualTLSFromFiles( "/etc/glide/client.pem", "/etc/glide/client.key", config.WithReloadInterval(60), ) if err != nil { return err }
advancedConfig := config.NewAdvancedClusterClientConfiguration(). WithTlsConfiguration(tlsConfig)
clientConfig := config.NewClusterClientConfiguration(). WithAddress(&config.NodeAddress{Host: "address.example.com", Port: 6379}). WithUseTLS(true). WithAdvancedConfiguration(advancedConfig)
client, err := glide.NewClusterClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}Loading PEM material from files
Section titled “Loading PEM material from files”When static, byte-based mTLS is desired but the material lives on disk, each SDK offers a helper that reads the PEM files and returns the bytes. Feed those bytes into the byte-based entry point shown above.
The same file-loading helpers work for both GlideClient (standalone) and GlideClusterClient (cluster-mode). The examples below show the standalone client; substitute the cluster variant if you are connecting to a cluster.
from glide import ( AdvancedGlideClientConfiguration, GlideClient, GlideClientConfiguration, NodeAddress, TlsAdvancedConfiguration,)from glide import load_client_certificate_and_key_from_file
cert, key = load_client_certificate_and_key_from_file( "/etc/glide/client.pem", "/etc/glide/client.key",)
tls_config = TlsAdvancedConfiguration(client_cert_pem=cert, client_key_pem=key)
advanced_config = AdvancedGlideClientConfiguration(tls_config=tls_config)
client_config = GlideClientConfiguration( addresses=[NodeAddress(host="primary.example.com", port=6379)], use_tls=True, advanced_config=advanced_config,)
client = await GlideClient.create(client_config)import glide.api.GlideClient;import glide.api.models.configuration.AdvancedGlideClientConfiguration;import glide.api.models.configuration.GlideClientConfiguration;import glide.api.models.configuration.NodeAddress;import glide.api.models.configuration.TlsAdvancedConfiguration;import glide.api.models.configuration.TlsAdvancedConfiguration.TlsAdvancedConfigurationBuilder;
byte[] cert = TlsAdvancedConfigurationBuilder.loadClientCertificateFromFile("/etc/glide/client.pem");byte[] key = TlsAdvancedConfigurationBuilder.loadClientKeyFromFile("/etc/glide/client.key");
TlsAdvancedConfiguration tlsConfig = TlsAdvancedConfiguration.builder() .useMutualTls(cert, key) .build();
AdvancedGlideClientConfiguration advancedConfig = AdvancedGlideClientConfiguration.builder() .tlsAdvancedConfiguration(tlsConfig) .build();
GlideClientConfiguration config = GlideClientConfiguration.builder() .address(NodeAddress.builder().host("primary.example.com").port(6379).build()) .useTLS(true) .advancedConfiguration(advancedConfig) .build();
GlideClient client = GlideClient.createClient(config).get();import { GlideClient, MutualTls, loadClientCertificateAndKeyFromFile,} from "@valkey/valkey-glide";
const { cert, key } = await loadClientCertificateAndKeyFromFile( "/etc/glide/client.pem", "/etc/glide/client.key",);
const mutualTls: MutualTls = { kind: "bytes", clientCertificate: cert, clientKey: key,};
const client = await GlideClient.createClient({ addresses: [{ host: "primary.example.com", port: 6379 }], useTLS: true, advancedConfiguration: { tlsAdvancedConfiguration: { mutualTls }, },});import ( glide "github.com/valkey-io/valkey-glide/go/v2" "github.com/valkey-io/valkey-glide/go/v2/config")
func ConnectStandaloneWithMutualTLSFromFileLoader() error { cert, key, err := config.LoadClientCertificateAndKeyFromFile( "/etc/glide/client.pem", "/etc/glide/client.key", ) if err != nil { return err }
tlsConfig, err := config.NewTlsConfiguration().WithMutualTLS(cert, key) if err != nil { return err }
advancedConfig := config.NewAdvancedClientConfiguration(). WithTlsConfiguration(tlsConfig)
clientConfig := config.NewClientConfiguration(). WithAddress(&config.NodeAddress{Host: "primary.example.com", Port: 6379}). WithUseTLS(true). WithAdvancedConfiguration(advancedConfig)
client, err := glide.NewClient(clientConfig) if err != nil { return err } defer client.Close()
return nil}Common Pitfalls
Section titled “Common Pitfalls”- mTLS still needs TLS enabled at the top level. The advanced TLS configuration only supplies the client-side material; without TLS on the base client configuration (
use_tls=True,.useTLS(true),useTLS: true, or.WithUseTLS(true)), the client connects in plaintext and the mTLS material is not used. - Path-based and byte-based mTLS are mutually exclusive. Supplying both a certificate/key path and inline PEM bytes on the same configuration is a configuration error in every SDK.
- Sub-second, zero, negative, and oversized reload intervals are rejected. The custom interval is validated at configuration time: it must be a positive whole number of seconds no greater than 4,294,967,295 (the maximum value of an unsigned 32-bit integer, roughly 136 years). If you want static mTLS from files, load the bytes yourself with the file-loading helper and use the byte-based mode.
- Byte-based mTLS is static. The material is read once at connect time and never reloads. Use a path-based mode when the certificate rotates.
- Reload cadence is a lower bound. The interval bounds how stale the on-disk material can be before the next reload attempt; the next successful reload takes effect on the next reconnect, not on open connections.
- Reload failures keep the last known-good material. A path that becomes unreadable, a mismatched key, or a corrupt certificate causes the reload to fail. The core keeps the last successfully loaded material and retries at the next tick.
- File permissions matter. The process user must have read access to the certificate and key files. Restrict the key file to that user; do not commit it or log it.
TLS Certificate Format
Section titled “TLS Certificate Format”All certificates must be in PEM format. A PEM certificate looks like this:
-----BEGIN CERTIFICATE-----MIIDXTCCAkWgAwIBAgIJAKL0UG+mRKmzMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV...-----END CERTIFICATE-----Troubleshooting TLS Connections
Section titled “Troubleshooting TLS Connections”Common Issues:
-
Certificate Verification Failed
- Ensure the certificate is valid and not expired
- Verify the hostname matches the certificate’s Common Name (CN) or Subject Alternative Name (SAN)
- Check that the certificate chain is complete
-
Connection Refused
- Verify the server is configured to accept TLS connections
- Ensure the port number is correct (typically 6379 for TLS)
-
Empty Certificate Error
- Do not provide empty certificate data
- Either provide valid certificates or use the default system certificates
-
File Not Found
- Verify the certificate file path is correct
- Ensure the file is accessible with proper read permissions