{"record":{"id":"8a2d969f0a77bc94","repo":"pathwaycom/pathway","slug":"mutual-tls-client-certificate-authentication-is","errorCode":null,"errorMessage":"Mutual TLS (client certificate) authentication is not supported by the Pulsar connector. Use TokenAuthentication or OAuth2Authentication instead.","messagePattern":"Mutual TLS \\(client certificate\\) authentication is not supported by the Pulsar connector\\. Use TokenAuthentication or OAuth2Authentication instead\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/pulsar/__init__.py","lineNumber":118,"sourceCode":"def _construct_pulsar_settings(\n    auth: PulsarAuthentication | None, subscription_type: str | None = None\n) -> api.PulsarSettings | None:\n    kwargs = auth._settings_kwargs() if auth is not None else {}\n    if subscription_type is not None:\n        kwargs[\"subscription_type\"] = subscription_type\n    if not kwargs:\n        return None\n    return api.PulsarSettings(**kwargs)\n\n\ndef _check_tls_settings(tls_settings: TLSSettings | None) -> None:\n    if tls_settings is None:\n        return\n    if (\n        tls_settings._client_cert_path is not None\n        or tls_settings._client_key_path is not None\n    ):\n        raise ValueError(\n            \"Mutual TLS (client certificate) authentication is not supported by \"\n            \"the Pulsar connector. Use TokenAuthentication or \"\n            \"OAuth2Authentication instead.\"\n        )\n\n\n@check_arg_types\n@trace_user_frame\ndef read(\n    uri: str,\n    topic: str,\n    *,\n    schema: type[Schema] | None = None,\n    format: Literal[\"plaintext\", \"raw\", \"json\"] = \"raw\",\n    mode: Literal[\"streaming\", \"static\"] = \"streaming\",\n    subscription_name: str | None = None,\n    subscription_type: (\n        Literal[\"reader\", \"shared\", \"key_shared\", \"exclusive\", \"failover\"] | None","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/pulsar/__init__.py#L100-L136","documentation":"Raised by pw.io.pulsar.read and pw.io.pulsar.write when the supplied TLSSettings include a client certificate or client key. The Pulsar connector supports only server-verifying TLS plus Token or OAuth2 authentication; mutual TLS is not implemented, so configuring client certs is rejected up front rather than failing obscurely at connection time.","triggerScenarios":"Passing tls_settings=TLSSettings(client_cert_path='cert.pem', client_key_path='key.pem') (or only one of the two) to pw.io.pulsar.read(...) or pw.io.pulsar.write(...).","commonSituations":"Reusing TLS settings copied from another Pathway connector (e.g. Kafka/Redpanda) that does support mTLS; corporate setups where brokers require client certificates; confusion between transport TLS (supported) and client-certificate auth (not supported).","solutions":["Remove client_cert_path/client_key_path from TLSSettings and authenticate with auth=pw.io.pulsar.TokenAuthentication(<jwt>) instead.","For OAuth2 flows, use auth=pw.io.pulsar.OAuth2Authentication(...) with your credentials provider.","If the broker truly requires mTLS, front it with a proxy or use a connector that supports client certs — do not try to force Pulsar settings through."],"exampleFix":"# before\ntls = pw.io.TLSSettings(client_cert_path=\"cert.pem\", client_key_path=\"key.pem\")\npw.io.pulsar.read(\"pulsar+ssl://host:6651\", \"topic\", schema=S, tls_settings=tls)\n\n# after\ntls = pw.io.TLSSettings()  # server-verifying TLS only\npw.io.pulsar.read(\"pulsar+ssl://host:6651\", \"topic\", schema=S, tls_settings=tls,\n                  auth=pw.io.pulsar.TokenAuthentication(\"my-jwt-token\"))","handlingStrategy":"validation","validationCode":"tls = pw.io.TLSSettings()\nassert tls._client_cert_path is None and tls._client_key_path is None\npw.io.pulsar.read(uri, topic, schema=S, tls_settings=tls,\n                 auth=pw.io.pulsar.TokenAuthentication(tok))","typeGuard":"def tls_is_server_only(tls) -> bool:\n    return tls is None or (tls._client_cert_path is None and tls._client_key_path is None)","tryCatchPattern":null,"preventionTips":["Do not copy mTLS settings from Kafka/Redpanda connectors into Pulsar calls.","Authenticate Pulsar with TokenAuthentication or OAuth2Authentication.","Keep TLS settings purely transport-level (CA path only) for Pulsar."],"tags":["pathway","pulsar","tls","authentication","unsupported"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}