Listener Configuration
In EMQX, listener is configured to receive requests from MQTT clients. EMQX supports the following message transfer protocols, including:
- TCP: port
1883 - SSL: port
8883 - Websocket listener:
8083 - Secure websocket listener:
8084
TIP
You can also configure listeners via Dashboard by clicking Management -> Listeners on the left navigation menu of the Dashboard. If you want to configure listeners from config files, it is recommended to use base.hocon instead of emqx.conf. This is because if the configuration is set in emqx.conf, any changes made through the Dashboard will only be temporary and will be lost upon EMQX restart.
TIP
EMQX offers more configuration items to better serve customized needs. For details, see the EMQX Enterprise Configuration Manual.
How EMQX Determines the Listener Address
A listener address determines the local network interfaces and port on which EMQX receives client connections.
A listener's bind setting accepts an explicit IP address and port, such as "0.0.0.0:1883", or a port alone, such as 1883. Starting from EMQX 6.3.0, the node-level node.default_listener_address setting controls the address used by listeners whose binds specify only a port.
EMQX selects the address in the following order:
- If
bindincludes an IP address, EMQX uses that address. Neithernode.default_listener_addressnor the security profile overrides it. - If
bindspecifies only a port andnode.default_listener_addressis set, EMQX uses the address selected by that setting on the local node. - Otherwise, MQTT listeners use the security profile's default: all network interfaces under
legacy, or the loopback address underhardened. The loopback address is accessible only from the local host.
The configured bind value stays unchanged. For example, bind = 1883 remains a port-only value even when the listener uses a specific IP address at runtime.
The TCP, SSL, and WebSocket configuration examples below use explicit IP addresses, so they are not affected by the default listener address setting.
For supported values and startup behavior, see Default Listener Address. The official Docker image sets its own default; see Listener Addresses in Docker.
Configure TCP Listener
TCP listener is a network service that listens for incoming TCP connections on a specific network port. It plays an essential role in establishing and managing connections between clients and EMQX over TCP/IP networks.
To configure the TCP listener in EMQX, you can add the listeners.tcp configuration items in the base.hocon file within the etc folder of the EMQX installation directory.
For example, to enable the TCP listener on port 1883, with a maximum 1,024,000 of concurrent connections allowed by the listener, you can work the code below:
listeners.tcp.default {
bind = "0.0.0.0:1883"
max_connections = 1024000
}where,
listeners.tcp.defaultis to enable the listener, and heredefaultis the name of the listener, you can change it to your own listener name.bindis to set the IP address and port of the listener, here it will listen to all incoming traffic from any IP address on port1883.max_connectionis to set the maximum number of concurrent connections allowed by the listener; default value:infinity.
Configure SSL Listener
SSL listener is a network service that listens for incoming SSL (Secure Sockets Layer) connections. In EMQX, it is used to secure network traffic between a client and EMQX by encrypting the data that is transmitted between them.
To configure the SSL listener in EMQX, you can add the listeners.ssl configuration items in the base.hocon file within the etc folder of the EMQX installation directory.
For example, to enable the SSL listener on port 8883, with a maximum 1,024,000 of concurrent connections allowed by the listener:
listeners.ssl.default {
bind = "0.0.0.0:8883"
max_connections = 1024000
ssl_options {
cacertfile = "etc/certs/cacert.pem"
certfile = "etc/certs/cert.pem"
keyfile = "etc/certs/key.pem"
verify = verify_none
fail_if_no_peer_cert = false
}
}where:
listeners.ssl.defaultis to enable the listener.bindis the IP address and port of the listener, here it will listen to all incoming traffic from any IP address on port8883.max_connectionis the maximum number of concurrent connections allowed by the listener, default value:infinity.ssl_optionsis the SSL/TLS configuration option for the listener, it has three properties:cacertfile: PEM file containing the trusted CA (certificate authority) certificates that the listener uses to verify the authenticity of the client certificates.certfile: PEM file containing the SSL/TLS certificate chain for the listener. If the certificate is not directly issued by a root CA, the intermediate CA certificates should be appended after the listener certificate to form a chain.keyfile: PEM file containing the private key corresponding to the SSL/TLS certificate.verify: Set 'verify_peer' to verify the authenticity of the clients' certificates, otherwise 'verify_none'.fail_if_no_peer_cert: If set totrue, the server fails if the client does not have a certificate to send, that is, sends an empty certificate. If set to false, it fails only if the client sends an invalid certificate (an empty certificate is considered valid).
Configure WebSocket Listener
A WebSocket listener is a network service that receives and processes messages over WebSocket. WebSocket support in EMQX allows clients to use the WebSocket protocol to connect to EMQX and exchange data in real-time.
For an overview of how MQTT over WebSocket works and typical usage scenarios, see MQTT over WebSocket.
To configure the WebSocket listener in EMQX, you can add the listeners.ws configuration items in the base.hocon file within the etc folder of the EMQX installation directory.
For example, to enable the WebSocket listener on port 8083, with a maximum 1,024,000 of concurrent connections allowed by the listener:
listeners.ws.default {
bind = "0.0.0.0:8083"
max_connections = 1024000
websocket.mqtt_path = "/mqtt"
}where:
listeners.ws.defaultis to enable the listener.bindis the IP address and port of the listener, here it will listen to all incoming traffic from any IP address on port8083.max_connectionis the maximum number of concurrent connections allowed by the listener, default value:infinity.websocket.mqtt_pathis to set the path to the WebSocket’s MQTT protocol, which is/mqttby default.
Configure Secure WebSocket Listener
A secure WebSocket listener is a WebSocket listener that uses the Secure Sockets Layer (SSL) or Transport Layer Security (TLS) protocol to encrypt the data exchanged between a WebSocket client and the broker. In EMQX, the secure WebSocket listener is an important security measure to protect sensitive data exchanged between WebSocket clients and EMQX>
To configure the secure WebSocket listener in EMQX, you can add the listeners.wss configuration items in the base.hocon file within the etc folder of the EMQX installation directory.
For example, to enable the Secure WebSocket listener on port 8084, with a maximum 1,024,000 of concurrent connections allowed by the listener:
listeners.wss.default {
bind = "0.0.0.0:8084"
max_connections = 1024000
websocket.mqtt_path = "/mqtt"
ssl_options {
cacertfile = "etc/certs/cacert.pem"
certfile = "etc/certs/cert.pem"
keyfile = "etc/certs/key.pem"
}
}where:
listeners.wss.defaultis to enable the listener.bindis the IP address and port of the listener, here it will listen to all incoming traffic from any IP address on port8084.max_connectionis the maximum number of concurrent connections allowed by the listener, default value:infinity.websocket.mqtt_pathis to set the path to the WebSocket’s MQTT protocol, which is/mqttby default.ssl_optionsis the SSL/TLS configuration option for the listener, it has three properties:cacertfile: PEM file containing the trusted CA (certificate authority) certificates that the listener uses to verify the authenticity of the client certificates.certfile: PEM file containing the SSL/TLS certificate chain for the listener. If the certificate is not directly issued by a root CA, the intermediate CA certificates should be appended after the listener certificate to form a chain.keyfile: PEM file containing the private key corresponding to the SSL/TLS certificate.
Use a Different Address on Each Node
Listener configuration changes made through the Dashboard, REST API, or CLI are replicated across the cluster. If you put one node's IP address in bind, the listener cannot bind to that address on other nodes unless the IP address is configured on a local network interface of those nodes. To use a different address on each node, keep the listener's bind as a port and configure the default address separately on each node.
Use base.hocon for listener settings, and emqx.conf or environment variables for the node-level default listener address. For example, to use the host part of each node's Erlang node name:
Set the TCP listener's bind to
1883through the Dashboard, or configure the following in each node'setc/base.hocon:hoconlisteners.tcp.default.bind = 1883If a higher-priority configuration source already sets an explicit bind address, update that source instead. See Config Override Rules.
Add the following to each node's
emqx.conf:hoconnode.default_listener_address = "nodename"For Docker deployments, pass
-e EMQX_NODE__DEFAULT_LISTENER_ADDRESS=nodenametodocker run, or setEMQX_NODE__DEFAULT_LISTENER_ADDRESS: nodenamein the Docker Compose service'senvironmentsection. This overrides the official image'salldefault, which takes precedence over the value inemqx.conf.EMQX uses the host part after
@in the node name, resolving it at node startup if it is a hostname. Ensure that it resolves to an address available on that node. A hostname that cannot be resolved prevents the node from starting.Restart each node to apply
node.default_listener_address. This setting affects all port-only binds for MQTT listeners, gateway listeners, and the Dashboard HTTP listener on that node. Explicit IP addresses in listener binds remain unchanged.
You can also set EMQX_NODE__DEFAULT_LISTENER_ADDRESS in the node's environment. Environment variables take precedence over emqx.conf.
View Listener Address Information
Starting from EMQX 6.3.0, you can view the resolved address and its source without changing the listener's configured bind. Use either the CLI or the REST API to query a node.
Query a Node with the CLI
Run the following command on the node you want to check:
emqx ctl listenersCheck listen_on for the configured bind, resolved_address for the resolved IP, and resolved_address_from for the address source. Also check running to confirm whether the listener is running: a stopped listener can still report a resolved address. See Listener Address Information for field meanings, including what an empty resolved_address value means.
Query a Listener with the REST API
To check a listener through the REST API, use GET /api/v5/listeners/:id, for example GET /api/v5/listeners/tcp:default. The response reports the address on the node handling the request. Use API authentication as required.
The bind field keeps the configured value, including the port. resolved_address and resolved_address_from are read-only information; change bind or node.default_listener_address to change the address, rather than editing these response fields.
These queries cover MQTT listeners. For gateway listeners, use the gateway listener query.
Forwarded Client Address (WebSocket Listeners)
WebSocket and secure WebSocket listeners have two options that control how EMQX determines a client's source address when the listener sits behind a proxy or load balancer:
websocket.proxy_address_header: Specifies the HTTP header that carries the client IP address.websocket.proxy_port_header: Specifies the HTTP header that carries the client port.
Starting from EMQX 6.3.0, both options default to "". EMQX uses the corresponding TCP peer address or port for any option left empty. To obtain either value from a trusted proxy, explicitly configure the corresponding header name, such as x-forwarded-for or x-forwarded-port.
When the configured header is present on the WebSocket upgrade request, EMQX uses the first (leftmost) entry of the header value as the client's source IP address (or port) instead of the address of the real TCP peer. The derived address is what IP-based authorization rules, banned clients, flapping detection, and audit and trace logs see as the client's source IP. Configured header names are matched case-insensitively.
Trust Forwarded Address Headers Only Behind a Trusted Proxy
The header value determines the client source IP that EMQX uses, so it must be honored only when a trusted proxy sets it:
- If the listener is directly reachable by clients (no proxy in front), keep
proxy_address_headerandproxy_port_headerempty so that EMQX always uses the real TCP peer address. - If there is a proxy but it appends its observation to an inbound
X-Forwarded-Forheader instead of overwriting or stripping it (appending is the default behavior of most proxies, for example NGINX's$proxy_add_x_forwarded_for), the leftmost entry that EMQX reads is still the one supplied by the client, so the source IP can still be spoofed. Configure the proxy to overwrite the header with the address it observed, use the PROXY protocol instead, or set the options to"". - Do not try to disable the mechanism by pointing the option at an unused header name: a client can send a header by any name. The empty string is the only value a client can never supply.
When proxy_protocol = true is set on the listener, the client address comes from the PROXY protocol handshake, and these headers are not consulted.
Link Listener to a Configuration Zone
Each listener in EMQX is associated with a zone, which by default is set to a logical zone named default.
When a listener is linked to a specific zone, MQTT clients connected to that listener inherit the settings from that zone.
For more information, see the Zone Override section in the configuration documentation.
Mountpoint
Each listener can be configured with a mountpoint: a topic prefix that EMQX adds to topics used by clients connected through the listener. The prefix is added to topics in PUBLISH packets, SUBSCRIBE and UNSUBSCRIBE requests, and Will messages, and removed from the topics of messages delivered to the client. The mountpoint is transparent to the client and is commonly used to isolate topic spaces between groups of clients, for example in multi-tenant deployments.
listeners.tcp.demo {
bind = "0.0.0.0:1883"
mountpoint = "department-a/"
}The mountpoint supports the placeholders ${clientid}, ${username}, ${zone}, and ${client_attrs.NAME}. For example, with mountpoint = "${username}/", when a client with username u1 subscribes to sensors/#, the subscription is internally created as u1/sensors/#.
Incompatibility with Topic-Prefix Extension Features
Several EMQX features are triggered by publishing or subscribing to topics that start with a special $ prefix. EMQX adds the mountpoint prefix before it matches these prefixes. For example, if a client connects through a listener with mountpoint mp/ and publishes to $delayed/10/t, the broker receives the topic as mp/$delayed/10/t, which no longer starts with $delayed/. The feature is silently bypassed: EMQX routes the message as an ordinary message to the mounted literal topic, and no error is reported to the client.
Compatibility Limitation
Do not configure a mountpoint on listeners whose clients use any of the following features:
| Feature | Topic Prefix |
|---|---|
| Delayed Publish | $delayed/ |
| File Transfer | $file/, $file-async/, $file-response/ |
| Message Queue | $queue/ |
| MQTT Streams | $stream/ |
| Cluster Linking | $LINK/ |
| Dynamic Keep Alive Adjustment | $SETOPTS/ |
| A2A over MQTT | $a2a/ |
For Cluster Linking, the mountpoint must not be set on the listener that accepts connections from the linked cluster. For A2A over MQTT, a mountpoint of exactly one topic level (for example acme/) still works: EMQX parses it as a namespace prefix on $a2a topics.
Shared subscriptions ($share/{group}/) and exclusive subscriptions ($exclusive/) are exceptions: they work with a mountpoint. EMQX parses these subscription prefixes before applying the mountpoint, so the mountpoint is added only to the inner topic filter. For example, subscribing to $share/g/t through a listener with mountpoint mp/ joins the shared subscription group g on the topic mp/t.