pathwaycom/pathway · error · ValueError

Mutual TLS (client certificate) authentication is not suppor

Error message

Mutual TLS (client certificate) authentication is not supported by the Pulsar connector. Use TokenAuthentication or OAuth2Authentication instead.

What it means

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.

Source

Thrown at python/pathway/io/pulsar/__init__.py:118

def _construct_pulsar_settings(
    auth: PulsarAuthentication | None, subscription_type: str | None = None
) -> api.PulsarSettings | None:
    kwargs = auth._settings_kwargs() if auth is not None else {}
    if subscription_type is not None:
        kwargs["subscription_type"] = subscription_type
    if not kwargs:
        return None
    return api.PulsarSettings(**kwargs)


def _check_tls_settings(tls_settings: TLSSettings | None) -> None:
    if tls_settings is None:
        return
    if (
        tls_settings._client_cert_path is not None
        or tls_settings._client_key_path is not None
    ):
        raise ValueError(
            "Mutual TLS (client certificate) authentication is not supported by "
            "the Pulsar connector. Use TokenAuthentication or "
            "OAuth2Authentication instead."
        )


@check_arg_types
@trace_user_frame
def read(
    uri: str,
    topic: str,
    *,
    schema: type[Schema] | None = None,
    format: Literal["plaintext", "raw", "json"] = "raw",
    mode: Literal["streaming", "static"] = "streaming",
    subscription_name: str | None = None,
    subscription_type: (
        Literal["reader", "shared", "key_shared", "exclusive", "failover"] | None

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Remove client_cert_path/client_key_path from TLSSettings and authenticate with auth=pw.io.pulsar.TokenAuthentication(<jwt>) instead.
  2. For OAuth2 flows, use auth=pw.io.pulsar.OAuth2Authentication(...) with your credentials provider.
  3. 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.

Example fix

# before
tls = pw.io.TLSSettings(client_cert_path="cert.pem", client_key_path="key.pem")
pw.io.pulsar.read("pulsar+ssl://host:6651", "topic", schema=S, tls_settings=tls)

# after
tls = pw.io.TLSSettings()  # server-verifying TLS only
pw.io.pulsar.read("pulsar+ssl://host:6651", "topic", schema=S, tls_settings=tls,
                  auth=pw.io.pulsar.TokenAuthentication("my-jwt-token"))
Defensive patterns

Strategy: validation

Validate before calling

tls = pw.io.TLSSettings()
assert tls._client_cert_path is None and tls._client_key_path is None
pw.io.pulsar.read(uri, topic, schema=S, tls_settings=tls,
                 auth=pw.io.pulsar.TokenAuthentication(tok))

Type guard

def tls_is_server_only(tls) -> bool:
    return tls is None or (tls._client_cert_path is None and tls._client_key_path is None)

Prevention

When it happens

Trigger: 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(...).

Common situations: 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).

Understand the failure class

Related errors


AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15). Data as JSON: /api/errors/8a2d969f0a77bc94. Report an issue: GitHub.