fluent/fluentd · error · Fluent::ConfigError
private_key_path is required when cert_path is specified
Error message
private_key_path is required when cert_path is specified
What it means
cert_option_server_validate! (cert_option.rb:70-73) requires that a <transport tls> (or equivalent TLS server) configuration specifying cert_path must also specify private_key_path: an OpenSSL server context needs both the certificate and its private key to handshake. Without the key, no certificate can be presented, so fluentd raises this Fluent::ConfigError at startup rather than failing later at connection time.
Source
Thrown at lib/fluent/plugin_helper/cert_option.rb:71
sandbox = Class.new
ctx.verify_callback = if File.exist?(conf.cert_verifier)
verifier = File.read(conf.cert_verifier)
sandbox.instance_eval(verifier, File.basename(conf.cert_verifier))
else
sandbox.instance_eval(conf.cert_verifier)
end
end
Fluent::TLS.set_version_to_context(ctx, version, conf.min_version, conf.max_version)
ctx.ciphers = ciphers unless insecure
ctx
end
def cert_option_server_validate!(conf)
case
when conf.cert_path
raise Fluent::ConfigError, "private_key_path is required when cert_path is specified" unless conf.private_key_path
log.warn "For security reason, setting private_key_passphrase is recommended when cert_path is specified" unless conf.private_key_passphrase
cert_option_load(conf.cert_path, conf.private_key_path, conf.private_key_passphrase)
when conf.ca_cert_path
raise Fluent::ConfigError, "ca_private_key_path is required when ca_cert_path is specified" unless conf.ca_private_key_path
log.warn "For security reason, setting ca_private_key_passphrase is recommended when ca_cert_path is specified" unless conf.ca_private_key_passphrase
generate_opts = cert_option_cert_generation_opts_from_conf(conf)
cert_option_generate_server_pair_by_ca(
conf.ca_cert_path,
conf.ca_private_key_path,
conf.ca_private_key_passphrase,
generate_opts
)
when conf.insecure
log.warn "insecure TLS communication server is configured (using 'insecure' mode)"
generate_opts = cert_option_cert_generation_opts_from_conf(conf)
cert_option_generate_server_pair_self_signed(generate_opts)View on GitHub (pinned to dd45c6e18d)
Solutions
- Add private_key_path /etc/fluent/server.key next to cert_path in <transport tls>
- Verify both files exist and the key matches the cert: openssl x509 -noout -modulus -in cert.pem | openssl md5 vs openssl rsa -noout -modulus -in server.key | openssl md5
- If the key is passphrase-protected, also set private_key_passphrase (fluentd warns when it is missing)
- Check your templating/secret injection actually rendered the private_key_path value (empty strings are treated as unspecified)
Example fix
# before <transport tls> cert_path /etc/fluent/server-cert.pem </transport> # => private_key_path is required when cert_path is specified # after <transport tls> cert_path /etc/fluent/server-cert.pem private_key_path /etc/fluent/server-key.pem </transport>
Defensive patterns
Strategy: validation
Validate before calling
tls = { 'cert_path' => '/etc/fluent/cert.pem', 'private_key_path' => '/etc/fluent/key.pem' }
raise 'private_key_path missing' if tls['cert_path'] && !tls['private_key_path']
raise 'cert file missing PEM' unless File.read(tls['cert_path']).include?('BEGIN CERTIFICATE') Try / catch
begin
agent.configure(conf)
rescue Fluent::ConfigError => e
if e.message.include?('private_key_path is required')
abort 'add private_key_path to <transport tls> and redeploy'
end
raise
end Prevention
- Pin TLS config templates to always emit cert_path and private_key_path as a pair (fail the template if either variable is unset)
- Validate rendered configs with fluentd --dry-run in CI before they reach production
- Keep cert/key pairs co-located in secret stores so one is never provisioned without the other
When it happens
Trigger: Config with <transport tls> cert_path /path/cert.pem but no private_key_path line — e.g. cert and key split across template variables and the key variable was empty, or the operator assumed the key would be found next to the cert. Raised during plugin configuration when the server helper builds the SSL context.
Common situations: Copy-paste TLS configs where the private_key_path line was dropped; secret-management systems injecting the cert but failing to inject the key; migrating from a client-only TLS config (which needs just ca_path) into a server config; typos in the parameter name such as private_keypath going unnoticed until startup.
Related errors
- ca_private_key_path is required when ca_cert_path is specifi
- no valid cert options configured. specify either 'cert_path'
- cert_path does not contain a valid certificate
- Cannot enable FIPS compliant mode. OpenSSL FIPS configuratio
- Plugin @id or path for <storage> required when 'persistent'
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/7b4ceaf43cdb2d05.
Report an issue: GitHub.