xai-org/x-algorithm · critical · FileNotFoundError

Kafka mTLS requires CA at {ca_file!r} (mount internal-ca Con

Error message

Kafka mTLS requires CA at {ca_file!r} (mount internal-ca ConfigMap or set SSL_CA_FILE)

What it means

create_mtls_ssl_context builds the SSL context Kafka clients use for mutual TLS. It reads SSL_CA_FILE (default /etc/ssl/internal-ca/ca-bundle.crt) and raises FileNotFoundError when the CA bundle is absent, because mTLS cannot verify brokers without a trusted CA. The message points at the internal-ca ConfigMap mount, indicating a k8s deployment expectation.

Source

Thrown at grox/libs/kafka_cli/mtls.py:11

import logging
import os
import ssl

logger = logging.getLogger(__name__)


def create_mtls_ssl_context() -> ssl.SSLContext:
    ca_file = os.getenv("SSL_CA_FILE", "/etc/ssl/internal-ca/ca-bundle.crt")
    if not ca_file or not os.path.exists(ca_file):
        raise FileNotFoundError(
            f"Kafka mTLS requires CA at {ca_file!r} (mount internal-ca ConfigMap or set SSL_CA_FILE)"
        )

    ssl_ctx = ssl.create_default_context(cafile=ca_file)
    ssl_ctx.verify_mode = ssl.CERT_REQUIRED
    ssl_ctx.check_hostname = False
    logger.info(f"Kafka mTLS: CERT_REQUIRED ca={ca_file} check_hostname=False")

    cert_file = os.getenv("SSL_CERT_FILE", "/etc/ssl/s2s/client/tls.crt")
    key_file = os.getenv("SSL_KEY_FILE", "/etc/ssl/s2s/client/tls.key")
    if not os.path.exists(cert_file) and os.path.exists("/certs/client.fullchain"):
        cert_file = "/certs/client.fullchain"
    if not os.path.exists(key_file) and os.path.exists("/certs/client.key"):
        key_file = "/certs/client.key"

    if os.path.exists(cert_file) and os.path.exists(key_file):
        ssl_ctx.load_cert_chain(certfile=cert_file, keyfile=key_file)
        logger.info(f"mTLS client certificate loaded: CERT={cert_file} KEY={key_file}")

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Mount the internal-ca ConfigMap at /etc/ssl/internal-ca in the pod spec (volumes + volumeMounts).
  2. Or set SSL_CA_FILE to an existing CA bundle path in the container: export SSL_CA_FILE=/path/to/ca-bundle.crt.
  3. Verify with kubectl exec -- ls -l /etc/ssl/internal-ca/ that the file is actually present after deployment.

Example fix

# before
# pod started without the ConfigMap -> FileNotFoundError on consumer start

# after (deployment.yaml)
containers:
- name: app
  volumeMounts:
  - name: internal-ca
    mountPath: /etc/ssl/internal-ca
volumes:
- name: internal-ca
  configMap:
    name: internal-ca
Defensive patterns

Strategy: validation

Validate before calling

ca = os.getenv('SSL_CA_FILE', '/etc/ssl/internal-ca/ca-bundle.crt')
if not os.path.isfile(ca):
    raise SystemExit(f'CA bundle missing at {ca}; mount internal-ca ConfigMap')

Try / catch

try:
    await consumer.start()
except FileNotFoundError as e:
    if 'internal-ca' in str(e):
        logger.error('mTLS CA not mounted; check ConfigMap volumes')
    raise

Prevention

When it happens

Trigger: Starting a Kafka consumer/producer region with security protocol SSL/mTLS where SSL_CA_FILE is unset and /etc/ssl/internal-ca/ca-bundle.crt does not exist in the container filesystem (ConfigMap not mounted, wrong path, or bare-metal run without the file).

Common situations: Running the service locally or in CI without the internal CA mount; deploying to k8s with the volumes/volumeMounts block missing or mounted at a different path; SSL_CA_FILE pointing to a path that exists in one image but not another.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/0357f67e0aefaf84. Report an issue: GitHub.