{"record":{"id":"174936b570723ea9","repo":"xai-org/x-algorithm","slug":"scramkafkaproducer-requires-an-ssl-config","errorCode":null,"errorMessage":"ScramKafkaProducer requires an ssl config","messagePattern":"ScramKafkaProducer requires an ssl config","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"grox/libs/kafka_cli/producer.py","lineNumber":146,"sourceCode":"            raise\n\n\nclass _ScramKafkaProducerClient:\n    _cached_clients: dict[str, AIOKafkaProducer] = {}\n\n    @classmethod\n    async def _build_client(cls, config: KafkaProducerConfig) -> AIOKafkaProducer:\n        if isinstance(config.brokers, WilyConfig):\n            wily = WilyNs(config.brokers)\n            instances = await wily.resolve(config.dest)\n            brokers = \",\".join(\n                f\"{instance.address}:{instance.port}\" for instance in instances\n            )\n        else:\n            brokers = \",\".join(config.brokers)\n        ssl_conf = config.ssl\n        if ssl_conf is None:\n            raise ValueError(\"ScramKafkaProducer requires an ssl config\")\n\n        proto = (ssl_conf.security_protocol or \"\").upper()\n        if proto == \"SSL\":\n            ssl_context = _create_mtls_ssl_context()\n            producer = AIOKafkaProducer(\n                bootstrap_servers=brokers,\n                security_protocol=\"SSL\",\n                ssl_context=ssl_context,\n                request_timeout_ms=config.timeout_sec * 1000,\n            )\n        else:\n            ssl_context = ssl.create_default_context()\n            ssl_context.check_hostname = False\n            ssl_context.verify_mode = ssl.CERT_NONE\n            producer = AIOKafkaProducer(\n                bootstrap_servers=brokers,\n                sasl_mechanism=ssl_conf.sasl_mechanism,\n                security_protocol=ssl_conf.security_protocol,","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/grox/libs/kafka_cli/producer.py#L128-L164","documentation":"ScramKafkaProducer._build_client (invoked from get()) builds the aiokafka client from KafkaProducerConfig; when config.ssl is None it raises ValueError because the SCRAM producer is designed to run only over TLS — plaintext SCRAM would leak credentials. Other producers in this codebase use SSL/mTLS config, so ssl=None is treated as misconfiguration.","triggerScenarios":"Constructing/getting a ScramKafkaProducer with a KafkaProducerConfig that omits the ssl field (defaults to None), e.g. config built from a source lacking the ssl block.","commonSituations":"Config template that only sets brokers and group but no ssl section; migrating a local plaintext producer config to the SCRAM class without adding TLS; YAML indentation putting ssl under the wrong parent key so it parses as absent.","solutions":["Add an ssl (SSLConfig) block to the producer config with security_protocol SASL_SSL and the appropriate context/mechanism settings.","If you do not need SCRAM, use the non-SCRAM producer class that permits plaintext.","Validate the config source includes the ssl section before building the client."],"exampleFix":"# before\ncfg = KafkaProducerConfig(brokers=['b:9092'])\nproducer = ScramKafkaProducer.get(cfg)  # ValueError: requires an ssl config\n\n# after\ncfg = KafkaProducerConfig(\n    brokers=['b:9092'],\n    ssl=SSLConfig(security_protocol='SASL_SSL'),\n)\nproducer = ScramKafkaProducer.get(cfg)","handlingStrategy":"validation","validationCode":"if config.ssl is None:\n    raise SystemExit('SCRAM producer requires ssl config; add SASL_SSL block')\nproducer = ScramKafkaProducer.get(config)","typeGuard":null,"tryCatchPattern":"try:\n    p = ScramKafkaProducer.get(cfg)\nexcept ValueError as e:\n    if 'ssl config' in str(e):\n        cfg = cfg.model_copy(update={'ssl': SSLConfig(security_protocol='SASL_SSL')})\n        p = ScramKafkaProducer.get(cfg)\n    else:\n        raise","preventionTips":["Require the ssl block in producer config schemas","Use different config classes for plaintext vs SCRAM setups"],"tags":["kafka","scram","ssl","configuration"],"backgroundTag":"missing-tls-configuration","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}