YunaiV/ruoyi-vue-pro · critical · RuntimeException
MQTT Client 启动失败: 连接 Broker 失败
Error message
MQTT Client 启动失败: 连接 Broker 失败
What it means
Thrown by startMqttClient() when connectMqttClient() returns false. connectMqttClient() calls client.connect(port, host).get(connectTimeoutSeconds) and returns false on ANY exception (logged at line 366). So this RuntimeException means the EMQX protocol's MQTT client could not establish a connection to the broker during startup. Unlike runtime disconnects (handled by the reconnect checker), a startup failure aborts the protocol.
Source
Thrown at yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/emqx/IotEmqxProtocol.java:256
httpServer.close().toCompletionStage().toCompletableFuture()
.get(5, TimeUnit.SECONDS);
log.info("[stopHttpServer][IoT EMQX 协议 {} HTTP Hook 服务已停止]", getId());
} catch (Exception e) {
log.error("[stopHttpServer][IoT EMQX 协议 {} HTTP Hook 服务停止失败]", getId(), e);
} finally {
httpServer = null;
}
}
// ======================================= MQTT Client ======================================
private void startMqttClient() {
// 1.1 创建 MQTT Client
MqttClient client = createMqttClient();
this.mqttClient = client;
// 1.2 连接 MQTT Broker
if (!connectMqttClient(client)) {
throw new RuntimeException("MQTT Client 启动失败: 连接 Broker 失败");
}
// 2. 启动定时重连检查
startMqttClientReconnectChecker();
}
private void stopMqttClient() {
MqttClient client = this.mqttClient;
this.mqttClient = null; // 先清理引用
if (client == null) {
return;
}
// 1. 批量取消订阅(仅在连接时)
if (client.isConnected()) {
List<String> topicList = emqxConfig.getMqttTopics();
if (CollUtil.isNotEmpty(topicList)) {
try {View on GitHub (pinned to 0418084e22)
Solutions
- Verify raw TCP reachability to the broker: telnet <mqtt-host> <mqtt-port> or nc -zv <host> <port>.
- Confirm emqx.mqtt-username / emqx.mqtt-password are correct and the broker auth backend accepts them.
- If mqtt-ssl=true, ensure the broker actually speaks TLS; for testing set trustAll=true (never in production) or provide a correct truststore under emqx.ssl-options.
- Increase emqx.connect-timeout-seconds for slow networks.
- Ensure the gateway's own HTTP Hook port is reachable from EMQX, since EMQX may reject the client if /mqtt/auth is unreachable.
Defensive patterns
Strategy: retry
Validate before calling
// before start(), test raw TCP connectivity to the broker
try (java.net.Socket s = new java.net.Socket()) {
s.connect(new java.net.InetSocketAddress(emqxConfig.getMqttHost(), emqxConfig.getMqttPort()),
emqxConfig.getConnectTimeoutSeconds() * 1000);
} catch (IOException e) {
throw new IllegalStateException("MQTT Broker 不可达: " + emqxConfig.getMqttHost() + ":" + emqxConfig.getMqttPort(), e);
} Try / catch
// allow the protocol to start even if the broker is briefly down; rely on the reconnect checker
try {
startMqttClient();
} catch (RuntimeException e) {
log.warn("[start][MQTT 首次连接失败,将由重连检查器重试]", e);
startMqttClientReconnectChecker(); // already exists for runtime reconnects
} Prevention
- Ensure the EMQX broker is deployed and reachable before starting the gateway.
- Validate MQTT credentials against the broker (mosquitto_pub / mqttx) before wiring them into config.
- Match mqtt-ssl to the broker's TLS setting; set trustAll=true only for local testing.
- Keep connect-timeout-seconds generous enough for slow networks.
- Leverage the existing reconnect checker so a transient broker outage at boot doesn't hard-fail the protocol.
When it happens
Trigger: emqx.mqtt-host / emqx.mqtt-port wrong or broker not running; MQTT username/password rejected by the broker's auth backend; TLS mismatch (mqtt-ssl=true against a plaintext broker, or trustAll=false without a valid truststore); firewall blocking the port; connect-timeout-seconds too short for a slow network.
Common situations: EMQX broker not deployed yet; wrong MQTT credentials in config; corporate firewall; TLS self-signed cert with trustAll=false; connect-timeout-seconds left low; the broker's /mqtt/auth hook itself cannot reach this gateway (chicken-and-egg at boot).
Related errors
- HTTP Hook 服务启动失败
- Modbus 读取失败 [slaveId=%d, identifier=%s, functionCode=%d, add
- Modbus 写入失败 [slaveId=%d, identifier=%s, address=%d]
- [startTcpServer][TCP Server 启动失败]
- 未知的序列化类型:{}
AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14).
Data as JSON: /api/errors/92271a17d0311864.
Report an issue: GitHub.