# TLS and WebSocket (/connectors/mqtt/how-to/tls-and-websocket)



The KubeMQ MQTT connector exposes up to three listeners at once: plain **TCP** on `1883`, **TLS**
over TCP on `8883`, and **WebSocket** on `8083` (path `/`). All three support both MQTT 3.1.1 and
MQTT 5.0. Each listener can be enabled or disabled independently.

<Callout type="info">
  TLS is configured server-side from the top-level &#x2A;*`Security`** block — there is no MQTT-specific
  TLS field. On a stock dev broker with no `Security` config, the TLS port is open but the listener
  is **not started**, so the examples use plain `tcp://`. For the shared TLS/security model across
  KubeMQ connectors, see [Auth & security](/connectors/reference/auth-and-security).
</Callout>

## Listeners at a glance [#listeners-at-a-glance]

| Listener    | Default port | URL scheme        | Env var to disable           |
| ----------- | ------------ | ----------------- | ---------------------------- |
| TCP (plain) | 1883         | `tcp://host:1883` | `CONNECTORSMQTT_PORT=""`     |
| TLS         | 8883         | `tls://host:8883` | `CONNECTORSMQTT_TLS_PORT=""` |
| WebSocket   | 8083         | `ws://host:8083/` | `CONNECTORSMQTT_WS_PORT=""`  |

The TCP listener is **always enabled** by default. The WebSocket listener is **always enabled** by
default. The TLS listener is **active only when a `Security` configuration is present** — on a
default (no-TLS-config) deployment the port is open but the listener is not started.

## The `KUBEMQ_MQTT_URL` selector [#the-kubemq_mqtt_url-selector]

Every example reads a single `KUBEMQ_MQTT_URL` environment variable (default
`tcp://localhost:1883`) and parses its **scheme** to select the transport — so the same example
binary runs over any of the three listeners by changing only the URL:

| URL scheme        | Transport    | Default port |
| ----------------- | ------------ | ------------ |
| `tcp://host:1883` | Plain TCP    | `1883`       |
| `tls://host:8883` | TLS over TCP | `8883`       |
| `ws://host:8083/` | WebSocket    | `8083`       |

```bash
# Plain TCP (default)
export KUBEMQ_MQTT_URL=tcp://my-kubemq-host:1883

# TLS
export KUBEMQ_MQTT_URL=tls://my-kubemq-host:8883

# WebSocket (note the trailing path)
export KUBEMQ_MQTT_URL=ws://my-kubemq-host:8083/
```

## TLS listener — `tls://host:8883` [#tls-listener--tlshost8883]

| Requirement              | Details                                                                                         |
| ------------------------ | ----------------------------------------------------------------------------------------------- |
| KubeMQ `Security` config | Must be configured (`Security.CertFile`, `Security.KeyFile`); the connector derives TLS from it |
| Minimum TLS version      | 1.2                                                                                             |
| Mutual TLS (mTLS)        | Supported — set `Security.CAFile`; the client must present a certificate                        |
| MQTT protocols           | Both 3.1.1 and 5.0                                                                              |

<Tabs groupId="language" items="['Go','Python','Ruby']">
  <Tab value="Go">
    ```go
    // paho.golang over TLS. For mTLS, load the client cert + key into tlsCfg.
    import (
        "crypto/tls"
        "net/url"
    )

    tlsCfg := &tls.Config{
        // Server-only TLS in dev: set InsecureSkipVerify, or supply RootCAs.
        // For mTLS: also set Certificates with the client cert + key.
        MinVersion: tls.VersionTLS12,
    }
    brokerURL, _ := url.Parse("tls://broker:8883")
    conn, err := autopaho.NewConnection(ctx, autopaho.ClientConfig{
        BrokerUrls: []*url.URL{brokerURL},
        TlsCfg:     tlsCfg,
        KeepAlive:  30,
    })
    ```
  </Tab>

  <Tab value="Python">
    ```python
    # paho-mqtt over TLS. Omit certfile/keyfile for server-only TLS.
    import ssl
    import paho.mqtt.client as mqtt
    from paho.mqtt.enums import CallbackAPIVersion

    client = mqtt.Client(
        callback_api_version=CallbackAPIVersion.VERSION2,
        protocol=mqtt.MQTTv5,
    )
    client.tls_set(
        ca_certs="ca.crt",       # server CA certificate
        certfile="client.crt",   # for mTLS; omit for server-only TLS
        keyfile="client.key",
        tls_version=ssl.PROTOCOL_TLS_CLIENT,
    )
    client.connect("broker", 8883, keepalive=30)
    ```
  </Tab>

  <Tab value="Ruby">
    ```ruby
    # The Ruby mqtt gem supports TLS over TCP via ssl: true (MQTT 3.1.1 only).
    require "mqtt"
    client = MQTT::Client.connect(
      host:    "broker",
      port:    8883,
      ssl:     true,
      version: "3.1.1",
    )
    ```
  </Tab>
</Tabs>

## WebSocket listener — `ws://host:8083/` [#websocket-listener--wshost8083]

The WebSocket listener accepts connections at path &#x2A;*`/`** (`ws://host:8083/`) and supports both
MQTT 3.1.1 and 5.0. Note the trailing path — the connector serves WebSocket MQTT at `/`, so include
it in the URL.

<Tabs groupId="language" items="['JavaScript','Go','Python','Java']">
  <Tab value="JavaScript">
    ```typescript
    // mqtt.js over WebSocket (MQTT 5.0).
    import * as mqtt from "mqtt";

    const client = mqtt.connect("ws://broker:8083/", {
      protocolVersion: 5,
      clientId: "my-ws-client",
      keepalive: 30,
      clean: true,
    });
    ```
  </Tab>

  <Tab value="Go">
    ```go
    // paho.golang over WebSocket — the URL scheme selects the transport.
    import "net/url"

    brokerURL, _ := url.Parse("ws://broker:8083/")
    conn, err := autopaho.NewConnection(ctx, autopaho.ClientConfig{
        BrokerUrls: []*url.URL{brokerURL},
        KeepAlive:  30,
    })
    ```
  </Tab>

  <Tab value="Python">
    ```python
    # paho-mqtt over WebSocket — transport="websockets" + ws_set_options(path="/").
    import paho.mqtt.client as mqtt
    from paho.mqtt.enums import CallbackAPIVersion

    client = mqtt.Client(
        callback_api_version=CallbackAPIVersion.VERSION2,
        transport="websockets",
        protocol=mqtt.MQTTv5,
    )
    client.ws_set_options(path="/")
    client.connect("broker", 8083, keepalive=30)
    ```
  </Tab>

  <Tab value="Java">
    ```java
    // Eclipse Paho MQTTv5 over WebSocket.
    MqttConnectionOptions opts = new MqttConnectionOptions();
    opts.setCleanStart(true);
    opts.setKeepAliveInterval(30);

    IMqttAsyncClient client = new MqttAsyncClient(
        "ws://broker:8083/",
        "my-ws-client",
        new MemoryPersistence());
    client.connect(opts).waitForCompletion();
    ```
  </Tab>
</Tabs>

<Callout type="info">
  The Ruby `mqtt` gem supports **TCP and TLS only** — it has **no WebSocket transport**. From Ruby,
  use the TLS listener for an encrypted channel.
</Callout>

## Disabling listeners [#disabling-listeners]

Set a port to an empty string (via environment variable) to disable that listener:

```bash
# Disable the TLS listener
CONNECTORSMQTT_TLS_PORT=""

# Disable the WebSocket listener
CONNECTORSMQTT_WS_PORT=""

# Disable plain TCP (requires TLS or WebSocket to remain active)
CONNECTORSMQTT_PORT=""
```

**Validation:** at least one of `Port`, `TlsPort`, `WsPort` must be non-empty, and all active ports
must be distinct.

## Related [#related]

<Cards>
  <Card title="Authentication" href="/connectors/mqtt/how-to/authentication" description="Password-as-JWT in the CONNECT packet — the same credential travels over TCP, TLS, or WebSocket." />

  <Card title="Auth & security" href="/connectors/reference/auth-and-security" description="The shared TLS/mTLS and JWT security model across KubeMQ connectors." />

  <Card title="Protocol versions" href="/connectors/mqtt/concepts/protocol-versions" description="All three transports carry both MQTT 3.1.1 and 5.0 — and 5.0 unlocks RPC and Queue consume." />
</Cards>
