zitadel/zitadel · error
TLS is enabled: please specify a key (path) and a cert (path
Error message
TLS is enabled: please specify a key (path) and a cert (path) or disable TLS if needed (e.g. by setting flag `--tlsMode external` or `--tlsMode disabled
What it means
ErrMissingConfig in internal/config/network/config.go is returned when TLS is enabled but the TLS config lacks a server key or certificate. ZITADEL refuses to start serving with incomplete TLS material and instructs the operator to provide key/cert or switch the TLS mode. It is a startup configuration error.
Source
Thrown at internal/config/network/config.go:10
package network
import (
"crypto/tls"
"errors"
"os"
)
var (
ErrMissingConfig = errors.New("TLS is enabled: please specify a key (path) and a cert (path) or disable TLS if needed (e.g. by setting flag `--tlsMode external` or `--tlsMode disabled")
)
type TLS struct {
//If enabled, ZITADEL will serve all traffic over TLS (HTTPS and gRPC)
//you must then also provide a private key and certificate to be used for the connection
//either directly or by a path to the corresponding file
Enabled bool
//Path to the private key of the TLS certificate, it will be loaded into the Key
//and overwrite any exising value
KeyPath string
//Path to the certificate for the TLS connection, it will be loaded into the Cert
//and overwrite any exising value
CertPath string
//Private key of the TLS certificate (KeyPath will this overwrite, if specified)
Key []byte
//Certificate for the TLS connection (CertPath will this overwrite, if specified)
Cert []byte
}View on GitHub (pinned to 13948f2bcd)
Solutions
- Provide the private key and certificate, either inline in the tls config or via key/cert path options
- If a proxy (e.g. nginx/traefik) terminates TLS, start ZITADEL with --tlsMode external
- For purely local/dev setups, disable TLS with --tlsMode disabled
- Verify configured cert/key paths exist and load successfully so Cert/Key are populated
Example fix
# before TLS: Enabled: true # after TLS: Enabled: true KeyPath: /etc/zitadel/tls/key.pem CertPath: /etc/zitadel/tls/cert.pem # or run with: --tlsMode external (proxy terminates TLS)
Defensive patterns
Strategy: validation
Validate before calling
if tlsCfg.Enabled && (tlsCfg.Key == nil || tlsCfg.Cert == nil) {
return errors.New("TLS enabled but key/cert missing: set keyPath/certPath or use --tlsMode external|disabled")
} Try / catch
// startup config is not catchable at runtime; validate before boot
if err := validateTLSConfig(cfg.TLS); err != nil {
log.Fatalf("invalid TLS configuration: %v", err)
} Prevention
- Match tlsMode to your deployment: disabled for dev, external behind a proxy, enabled only with key+cert provided
- Mount cert/key files in containers and verify paths in health/startup checks
- Document required TLS env vars in your deployment manifests
When it happens
Trigger: TLS enabled (default tlsMode) while tls.Key or tls.Cert are nil in the compiled Config — i.e. no key/cert given inline and no KeyPath/CertPath resolvable, via Config() at internal/config/network/config.go:47.
Common situations: Operator enables TLS but forgets to set the key/cert files in config.yaml or env vars; a path typo makes the file load fail leaving Cert/Key nil; running locally behind a reverse proxy while TLS stays enabled instead of --tlsMode external or disabled.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- unable to append rootCA
- MaxOpenConns of the database must be higher than 3 or 0 for
- cache connector %q not enabled
- invalid tlsMode: %w
- unable to read config: %w
AI-assisted analysis of zitadel/zitadel@13948f2bcd (2026-09-06).
Data as JSON: /api/errors/e8f693dd8fb616d4.
Report an issue: GitHub.