Release Date: 2025-06-10
Make sure to check the breaking changes and known issues before upgrading to EMQX 5.10.0.
Enhancements
Core MQTT Functionalities
- #15118 Provided a new configuration option
mqtt.subscription_max_qos_rules
to control the maximum QoS level allowed per client subscription. This allows administrators to limit the QoS requested in SUBSCRIBE packets based on matching rules for specific topics. Currently, only a limited set of matching rules (predicates) is supported, based on the topic in the SUBSCRIBE packet. - #15246 Improved WebSocket connections performance and resource consumption.
- Reduced CPU usage by approximately 20% and slightly lowered memory consumption, according to synthetic benchmarks measuring 1-on-1 MQTT messaging performance.
- Improved connection setup efficiency when the listener-wide connection limit is enabled, especially on nodes managing a large number of connections.
Deployment
- #14791 Added support for custom annotations on the EMQX StatefulSet in the Helm chart, enabling automated pod restarts on ConfigMap or Secret changes. This improves automation and reliability when managing EMQX on Kubernetes.
Access Control
- #15250 Improved LDAP bind authentication to correctly extract the
is_superuser
flag from LDAP entry attributes. Previously, theis_superuser
value was always set tofalse
, even when the LDAP entry included a validisSuperuser
attribute. -
#15249 Improved the LDAP authentication and authorization.
-
Validation for the LDAP
filter
/base_dn
settings was added. - Fixed various variable interpolation issues.
Rule Engine
-
#15001 Add
ai_completion
function to the Rule Engine SQL that allows to use AI services to process the data. -
#15201 Add
base_url
option to AI completion provider configuration. -
#15188 Rule event topics now have namespaces.
Previous event topic | New event topic |
---|---|
$events/client_connected |
$events/client/connected |
$events/client_disconnected |
$events/client/disconnected |
$events/client_connack |
$events/client/connack |
$events/client_check_authz_complete |
$events/auth/check_authz_complete |
$events/client_check_authn_complete |
$events/auth/check_authn_complete |
$events/session_subscribed |
$events/session/subscribed |
$events/session_unsubscribed |
$events/session/unsubscribed |
$events/message_delivered |
$events/message/delivered |
$events/message_acked |
$events/message/acked |
$events/message_dropped |
$events/message/dropped |
$events/delivery_dropped |
$events/message/delivery_dropped |
$events/message_transformation_failed |
$events/message_transformation/failed |
$events/schema_validation_failed |
$events/schema_validation/failed |
Previous event topics are kept for backwards compatibility.
- #15175 Added support for matching event topics in Rule Engine using wildcards. Now, it's possible to use
$events/#
,$events/sys/+
and similar for matching multiple events at once.
Smart Data Hub
- #15174 Added support to upload Protobuf source file bundles for Schema Registry.
For example, assuming that the Protobuf source file bundle is at /tmp/bundle.tar.gz
and has the following file structure, with a.proto
being the root Protobuf schema file:
.
├── a.proto
├── c.proto
└── nested
└── b.proto
Then, to create a new schema using that bundle via the HTTP API:
sh
curl -v http://127.0.0.1:18083/api/v5/schema_registry_protobuf/bundle \
-XPOST \
-H "Authorization: Bearer xxxx" \
-F bundle=@/tmp/bundle.tar.gz \
-F name=my_cool_schema \
-F root_proto_file=a.proto
Data Integration
-
#15248 EMQX supports data integration with Doris, supporting data writing using SQL statements.
-
#15218 Added support for IAM authentication in Kafka Producer and Consumer Connectors when connecting to Amazon MSK (Managed Streaming for Apache Kafka). When EMQX runs on AWS EC2, it uses the AWS SDK to generate OAuth Bearer tokens for Kafka clients.
-
#15157 Added support for specifying private key file path for Snowflake Connector instead of using password.
Users should either use password, private key, or neither (set parameters in /etc/odbc.ini
).
- #14983 EMQX supports data integration with S3Tables.
Current limitations:
- Only S3Tables catalogs are supported (hence table data and metadata must live in S3).
- Only Iceberg table format version 2 is supported.
- Only the following partition transform functions are supported:
- identity
- void
- bucket[N]
- Data files are written only in Avro.
-
#15331 Fixed the issue in influxdb action where the line protocol conversion failed when the
timestamp
inWriteSyntax
was left blank and there was no timestamp field in the rule. Now the system's current millisecond value is used instead, and millisecond precision is enforced. -
#15348 Make
middlebox_comp_mode
configurable for SSL clients. Themiddlebox_comp_mode
option, which was previously always enabled (true
) for all TLS 1.3 connections, is now configurable. By default, it remainstrue
to maintain compatibility with most network environments.
In rare cases where TLS fails with an error such as: unexpected_message, TLS client: In state hello_retry_middlebox_assert ...
, try setting middlebox_comp_mode
to false
.
Multi-Tenancy
- #15253 Added two new multi-tenancy APIs:
GET /mt/ns_list_details
andGET /mt/ns_list_managed_details
. Both work similarly to their existing counterpars, but returns extra metadata associated with the namespace besides its name. - #15160 Added the
DELETE /mt/bulk_delete_ns
API for multi-tenancy management, which allows deleting namespaces in bulk.
CLI
- #15158 Added new
emqx ctl conf remove x.y.z
command, which removes the configuration key pathx.y.z
from the existing configuration.
Gateway
- #15138 Introduced NATS Gateway for accepting NATS client connections over TCP/TLS, WS/WSS transport protocols.
For example, the NATS gateway will transform the following NATS message into an MQTT message with the topic sub/t
and payload hello
, while supporting seamless integration with existing EMQX features such as the rule engine, data integration, and more:
PUB sub.t 5
hello
Durable Storage
- #15043 Instrument the DS Raft backend with basic metrics to provide insights into cluster status, database overview, shard replication, and replica transitions.
Bug Fixes
Access Control
- #15184 Fixed an issue where the error message format was incorrect when creating a new banned list record failed.
Clustering
- #15304 Fixed the problem related to core node discovery by replicant nodes when using
static
discovery strategy.
Previously, the replicants could ignore core nodes not explicitly listed in the static_seeds
list.
This could lead to an inconsistent cluster view and load imbalance.
- #15180 Fixed an issue in
ekka_locker
where RPC (badrpc
) errors were not handled correctly, causing false-positive lock successes. This could lead to inconsistent lock states and deadlocks in clustered deployments.
Security
- #15159 Improved CRL Distribution Point (CDP) handling: If a CDP URL fails to refresh continuously (default timeout: 60 seconds), it will now be evicted and excluded from further refresh attempts to prevent repeated error logs.
Rule Engine
- #15247 Fixed an issue where
function_clause
error logs would be printed when attempting to callemqx ctl conf remove dashboard.sso.<BACKEND_NAME>
.
Smart Data Hub
- #15285 Added
content-type
header to External HTTP Schema requests. - #15224 Fixed an issue where updating an External Schema Registry via the dashboard would inadvertently change the password to
******
. - #15190 Support setting hard-coded QoS and topic in message transformation.
Data Integration
-
#15274 Now, any health check failure for Postgres, Matrix and TimescaleDB Connectors will trigger a full reconnection. Prior to this change, there were situations where the connection would become unusable and attempts to use it would hang, potentially leading to out of memory issues.
-
#15234 Added trace events for rule testing when either the Action is not installed yet, and for Republish Fallback actions. These will now appear in the frontend while testing Rules with simulated input data.
-
#15219 Reduced the amount of logs generated by Clickhouse Connector when a health check timeout occurs. Also, when a health check timeout occurs for this Connector, we now mark it as
connecting
instead ofdisconnected
, meaning that a full reconnect attempt will no longer be triggered by such timeouts. -
#15154 Fixed a rare race condition in Actions that run in aggregated mode (S3, Azure Blob Storage, Snowflake) that could result in crash logs similar to the following:
** Reason for termination ==
** {function_clause,[{emqx_connector_aggregator,handle_close_buffer,[...], ...
- #15147 When running Rule tests with simulated input data, some Actions would not emit trace events after rendering requests. This has been fixed.
Affected Actions: - Couchbase - Snowflake - IoTDB (Thrift driver)
- #15306 Fixed an issue where a Connector's health check response would always trigger health checks for all dependent Actions and Sources, regardless of their actual state.
Multi-Tenancy
- #15242 Fixed an issue where, upon node restart after configuring limiters for multi-tenancy, logs like the following would be logged while initializing limiters:
2025-05-15T16:45:13.276895+08:00 [error] clientid: ns3mqttx_620053b2_100, msg: hook_callback_exception, peername: 127.0.0.1:39364, username: ns3, reason: {limiter_group_not_found,{mt_tenant,<<"ns3">>}}, stacktrace: [{emqx_limiter,connect,1,[{file,"emqx_limiter.erl"},{line,134}]}
Observability
- #15299 Fixed a
badarg
error when exporting OpenTelemetry metrics.
Telemetry
- #15216 Fixed a crash of
emqx_telemetry
process when there are plugins activated.
Breaking Changes
- #15289 Added a new
resource_opts.health_check_timeout
configuration to all Connectors, Actions and Sources, with default value of 60 seconds. If a health check takes more than this to return a response, the Connector/Action/Source will be deemeddisconnected
.
Note: since the default is 60 seconds, this means that if a Connector/Action/Source previously could take more than that to return a healthy response, now it'll be deemed disconnected in such situations.
-
#15286 Configuration option
broker.routing.storage_schema
is now deprecated and ignored. Legacyv1
routing storage schema is no longer supported, and EMQX will refuse to start in a cluster running older versions that still use it. -
#15239 The type for the
multi_tenancy.default_max_sessions
is now eitherinfinity
or a positive integer. Previously,0
would be accepted. -
#15156 Schema validation was added to
dashboard.sso.oidc.issuer
field. Now, this value is checked to be a valid URL.