Download Latest Version emqx-enterprise-docker-amd64.tar.gz (146.3 MB)
Email in envelope

Get an email when there's a new version of emqx

Home / 6.1.1
Name Modified Size InfoDownloads / Week
Parent folder
emqx_username_quota-1.0.0.tar.gz 2026-02-26 43.4 kB
env.sh 2026-02-26 462 Bytes
emqx-enterprise-test.zip 2026-02-26 1.2 GB
emqx-enterprise-release.zip 2026-02-26 1.2 GB
emqx-enterprise-docker-sf-arm64.tar.gz 2026-02-26 218.0 MB
emqx-enterprise-docker-sf-amd64.tar.gz 2026-02-26 214.2 MB
emqx-enterprise-docker-arm64.tar.gz 2026-02-26 143.3 MB
emqx-enterprise-docker-amd64.tar.gz 2026-02-26 145.7 MB
emqx-enterprise-6.1.1-ubuntu24.04-arm64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-ubuntu24.04-arm64.tar.gz 2026-02-26 107.7 MB
emqx-enterprise-6.1.1-ubuntu24.04-arm64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-ubuntu24.04-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-ubuntu24.04-arm64.deb 2026-02-26 79.7 MB
emqx-enterprise-6.1.1-ubuntu24.04-amd64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-ubuntu24.04-amd64.tar.gz 2026-02-26 110.7 MB
emqx-enterprise-6.1.1-ubuntu24.04-amd64.deb 2026-02-26 80.3 MB
emqx-enterprise-6.1.1-ubuntu22.04-arm64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-ubuntu22.04-arm64.tar.gz 2026-02-26 107.3 MB
emqx-enterprise-6.1.1-ubuntu22.04-arm64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-ubuntu22.04-arm64.deb 2026-02-26 79.7 MB
emqx-enterprise-6.1.1-ubuntu22.04-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-ubuntu22.04-amd64.tar.gz 2026-02-26 110.5 MB
emqx-enterprise-6.1.1-ubuntu22.04-amd64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-macos15-arm64.zip.sha256 2026-02-26 65 Bytes
emqx-enterprise-6.1.1-ubuntu22.04-amd64.deb 2026-02-26 80.3 MB
emqx-enterprise-6.1.1-macos15-arm64.zip 2026-02-26 89.0 MB
emqx-enterprise-6.1.1-macos14-arm64.zip.sha256 2026-02-26 65 Bytes
emqx-enterprise-6.1.1-macos14-arm64.zip 2026-02-26 89.1 MB
emqx-enterprise-6.1.1-el9-arm64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el9-arm64.rpm.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el9-arm64.tar.gz 2026-02-26 107.4 MB
emqx-enterprise-6.1.1-el9-arm64.rpm 2026-02-26 80.7 MB
emqx-enterprise-6.1.1-el9-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el9-amd64.rpm.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el9-amd64.tar.gz 2026-02-26 110.6 MB
emqx-enterprise-6.1.1-el9-amd64.rpm 2026-02-26 81.3 MB
emqx-enterprise-6.1.1-el8-arm64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el8-arm64.tar.gz 2026-02-26 108.8 MB
emqx-enterprise-6.1.1-el8-arm64.rpm.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el8-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el8-arm64.rpm 2026-02-26 80.8 MB
emqx-enterprise-6.1.1-el8-amd64.tar.gz 2026-02-26 112.0 MB
emqx-enterprise-6.1.1-el8-amd64.rpm.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el8-amd64.rpm 2026-02-26 82.0 MB
emqx-enterprise-6.1.1-el7-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el7-amd64.tar.gz 2026-02-26 108.1 MB
emqx-enterprise-6.1.1-el7-amd64.rpm.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian13-arm64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-el7-amd64.rpm 2026-02-26 82.6 MB
emqx-enterprise-6.1.1-debian13-arm64.tar.gz 2026-02-26 108.7 MB
emqx-enterprise-6.1.1-debian13-arm64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian13-arm64.deb 2026-02-26 78.3 MB
emqx-enterprise-6.1.1-debian13-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian13-amd64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian13-amd64.tar.gz 2026-02-26 111.2 MB
emqx-enterprise-6.1.1-debian12-arm64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian13-amd64.deb 2026-02-26 79.6 MB
emqx-enterprise-6.1.1-debian12-arm64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian12-arm64.tar.gz 2026-02-26 107.4 MB
emqx-enterprise-6.1.1-debian12-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian12-arm64.deb 2026-02-26 78.2 MB
emqx-enterprise-6.1.1-debian12-amd64.tar.gz 2026-02-26 110.4 MB
emqx-enterprise-6.1.1-debian12-amd64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian11-arm64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian12-amd64.deb 2026-02-26 79.5 MB
emqx-enterprise-6.1.1-debian11-arm64.tar.gz 2026-02-26 107.2 MB
emqx-enterprise-6.1.1-debian11-arm64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian11-arm64.deb 2026-02-26 78.2 MB
emqx-enterprise-6.1.1-debian11-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian11-amd64.tar.gz 2026-02-26 110.3 MB
emqx-enterprise-6.1.1-debian11-amd64.deb.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-debian11-amd64.deb 2026-02-26 79.4 MB
emqx-enterprise-6.1.1-amzn2023-arm64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-amzn2023-arm64.tar.gz 2026-02-26 107.2 MB
emqx-enterprise-6.1.1-amzn2023-arm64.rpm.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-amzn2023-amd64.tar.gz.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-amzn2023-arm64.rpm 2026-02-26 80.7 MB
emqx-enterprise-6.1.1-amzn2023-amd64.tar.gz 2026-02-26 110.3 MB
emqx-enterprise-6.1.1-amzn2023-amd64.rpm.sha256 2026-02-26 64 Bytes
emqx-enterprise-6.1.1-amzn2023-amd64.rpm 2026-02-26 81.3 MB
emqx-enterprise_6.1.1_arm64.snap 2026-02-26 98.8 MB
emqx-enterprise_6.1.1_amd64.snap 2026-02-26 102.1 MB
EMQX Enterprise 6.1.1 source code.tar.gz 2026-02-26 6.0 MB
EMQX Enterprise 6.1.1 source code.zip 2026-02-26 7.9 MB
README.md 2026-02-26 30.1 kB
Totals: 85 Items   6.7 GB 13

Enhancements

Core MQTT Functionalities

  • #16637 Previously, if a session was taken over while in the middle of receiving several retained messages from a wildcard topic subscription, iteration over those retained messages would start over for the new client, repeating already delivered retained messages. Now, the new client will resume iteration from the last confirmed delivered message from the last session, reducing the number of duplicated retained messages.

Durable Storage

  • #16704 Prevent RocksDB storage backing Durable Storage shards from preallocating large chunks of disk space by default.

Previously, each shard consumed a significant amount of disk space immediately, which compounded due to multiple Durable Storage databases now being created by default (each consisting of 16 shards).

Message Queue and Streams

  • #16551, #16714 Refined Message Stream and Message Queue interfaces.

For stream subscriptions, the $stream prefix is now used. Streams are now named, and the name should be specified on subscribe: SUBSCRIBE $stream/<name>/<topic_filter> (or SUBSCRIBE $stream/<name> if the stream is known to exist). The starting point for stream consumption is specified using the stream-offset user subscription property.

For message queue subscriptions, the $queue prefix is used. Message queues are also named, and the name should be specified on subscribe: SUBSCRIBE $queue/<name>/<topic_filter> (or SUBSCRIBE $queue/<name> if the queue is known to exist).

Notes:

  • Stream and queue names may contain only alphanumeric characters, underscores, hyphens, and dots.
  • Previously created unnamed streams and queues obtain the name derived from their topic filter. Their name becomes their topic filter with prepended /.
  • The legacy $q queue interface (introduced in 6.0.0) and $s stream interface (introduced in 6.1.0) are kept for compatibility, but their use is discouraged.
  • If Message Queues are enabled, $queue prefix cannot be used for subscribing to shared subscriptions anymore.

  • #16820 Added shorter API path aliases /queues/* and /streams/* for the Message Queue and Message Stream management APIs.

The previous /message_queues/* and /message_streams/* paths remain functional for backward compatibility but are no longer shown in the API documentation.

Gateway

  • #16719 Added Block-Wise Transfer support for CoAP and LwM2M gateways.

  • Added block-wise settings: enable, max_block_size, max_body_size, and exchange_lifetime.

  • Improved POST /gateways/coap/clients/:clientid/request and LwM2M downlink handling for large block-wise messages.

  • #16736

  • Added the jt808.frame.parse_unknown_message option, enabling the JT808 gateway to transparently forward unknown messages.

  • Added JT/T 808 protocol 2019 support.

  • Added GBK character encoding support for JT/T 808 gateway.

    The JT/T 808 protocol specifies GBK encoding for STRING type fields. A new frame.string_encoding configuration option is added:

    • utf8 (default): Pass through strings as-is (backward-compatible)
    • gbk: Convert GBK-encoded strings from devices to UTF-8 for MQTT, and UTF-8 from MQTT to GBK for devices

    This affects both uplink parsing (GBK to UTF-8) and downlink serialization (UTF-8 to GBK), including string fields such as license plates, driver names, text messages, area names, and client parameters. MQTT payloads always use UTF-8 encoding regardless of this setting.

  • Added support for custom msg_sn in JT/T 808 gateway downlink messages.

    When a downlink MQTT message payload contains a msg_sn field in the header, the gateway will use that value instead of the auto-generated channel sequence number. This allows external systems to control message sequencing for specific use cases.

  • Fixed JT/T 808 gateway parameter setting (0x8103) and query response (0x0104) message handling for CAN bus ID parameters (0x0110~0x01FF), which should use BYTE[8] data type with base64 encoding in JSON instead of string type.

  • Fixed JT/T 808 0x0702 driver identity report message parsing.

Security

  • #16447 Added a new force_delete query parameter to the following HTTP APIs for managing certificates:

  • DELETE /certs/global/name/:name

  • DELETE /certs/ns/:ns/name/:name

When omitted or false, configurations in all namespaces will be checked to see if the managed bundle being deleted is being referenced and fail deletion if affirmative.

  • #16461 Support TLS 1.3 session ticket resumption.

EMQX now supports TLS 1.3 session resumption using stateless session tickets, allowing clients to resume TLS sessions without server-side session state storage.

Node-level configuration: node.tls_stateless_tickets_seed is the secret key seed for generating TLS 1.3 stateless session tickets. Listener-level configuration: listeners.ssl.<name>.ssl_options.session_tickets enables TLS 1.3 session resumption using stateless session tickets. Possible values are disabled (default), stateless, and stateless_with_cert (includes certificate information).

Session tickets are only generated when node.tls_stateless_tickets_seed is configured (non-empty) and session_tickets is enabled in listener SSL options. If session_tickets is enabled but node.tls_stateless_tickets_seed is empty, session tickets will not be generated and an error log will be emitted when starting the listener.

Access Control

  • #16504 Added a new option to parameterize the data source from which to construct the dashboard username when creating a new user via OIDC SSO.

  • #16741 Added configuration options idp_signs_envelopes and idp_signs_assertions to SAML SSO backend to control signature verification behavior.

Previously, SAML signature verification was not working correctly because the IdP certificate fingerprint was not being extracted from metadata and passed to esaml for verification.

Both options default to false for backwards compatibility with existing configurations. Users who want to enable signature verification should explicitly set these to true when their IdP is configured to sign SAML responses.

  • #16684 Enabled mqtt.client_attrs_init expressions can make sure of password (for example, feed it to jwt_value) to initialize client attribute.

  • #16730 Redis authorization now supports a compatibility mode for EMQX 4.x ACL data. Set compatibility_mode = v4 to enable legacy %u/%c placeholder conversion and legacy ACL access values 1|2|3 (mapped to subscribe/publish/all). By default, compatibility mode remains disabled, so existing Redis authz behavior is unchanged.

Data Integration

  • #16511 Supported the IoTDB Table Model in the data integration.

  • #16516 Added two new Action metrics: aggregated_upload.success and aggregated_upload.failure. These are only relevant for Aggregated Upload Actions (S3, Azure Blob Storage, Snowflake and S3Tables) and are incremented when an aggregated delivery succeeds or fails, respectively.

  • #16658 Previously, when the server port was omitted in an EMQX Tables Connector, the port would default to 80. Now, it defaults to 4001.

A more intelligible error message is returned when an EMQX Tables Connector is configured with SSL enabled but cacertfile, certfile or keyfile configurations are missing.

Rule Engine

  • #16524 Enhanced base64 encoding and decoding functions in rule engine SQL with support for padding and URL-safe options.

The base64_encode and base64_decode functions now support optional parameters to control encoding behavior:

  • no_padding: Encode or decode without padding characters (=). Useful when you need to remove padding from encoded strings or decode strings that don't have padding.
  • urlsafe: Use URL-safe base64 encoding/decoding. Replaces + with - and / with _, making the encoded string safe to use in URLs without encoding.

You can use these options individually or combine them. When combining options, the order doesn't matter.

Examples in rule SQL:

Encode without padding: sql SELECT base64_encode(payload, 'no_padding') as encoded FROM "t/#"

Encode with URL-safe characters: sql SELECT base64_encode(payload, 'urlsafe') as encoded FROM "t/#"

Encode with both options (no padding and URL-safe): sql SELECT base64_encode(payload, 'no_padding', 'urlsafe') as encoded FROM "t/#"

Decode URL-safe base64: sql SELECT base64_decode(payload, 'urlsafe') as decoded FROM "t/#"

Decode unpadded URL-safe base64: sql SELECT base64_decode(payload, 'urlsafe', 'no_padding') as decoded FROM "t/#"

  • #16533 Added two new Variform expression helper functions json_value and jwt_value to extract values from JSON data and JWT tokens using dot-separated key paths.

The json_value function extracts values from JSON binary strings using a dot-separated path to navigate nested structures. The jwt_value function decodes JWT token payloads and extracts claim values using the same path syntax.

For example, if username is a JSON object, you can access field with json_value(username, 'shop.floor'); if password is JWT with a customized claim, you can access the nested value with jwt_value(password, 'client_attrs.unitid').

  • #16539 Added support for keeping track of metric aliases when utilizing the spb_decode Rule Engine function.

Now, after a device or edge of network (EoN) node publishes its DBIRTH/NBIRTH messages, alias mappings in said message will be stored and used when the client later uses spb_decode on a message matching the DDATA/NDATA topic patterns. The original names of the metrics will be added to the output of spb_decode.

Note: when executing fallback actions, the mapping is not available in the environment they run in. This means that, if a fallback action republishes the undecoded DDATA/NDATA payload to a Sparkplug B DDATA/NDATA topic, the metric name fields will not be populated by the alias mapping.

  • #16581 Added a new Rule SQL function: spb_zip_kvs.

Given an already decoded, valid Sparkplug B message, it'll go through the metrics and "zip" each property name and its value together.

  • properties (and any nested PropertySet values) have their keys and values fields removed and the values of the two former fields zipped together and merged with the original map. Values that have the PropertySet or PropertySetList types are recursively transformed like this.

  • Values of PropertySetList type have their propertyset field removed and replaced by an array of PropertySets, transformed following the above item's description.

  • If present, dataset_value field is transformed in a similar fashion: its columns and rows fields are removed and their values zipped together in an object merged with the original object. types and num_of_columns fields are removed from output.

  • Other values/fields are untouched.

For example, given this input decoded Sparkplug B message:

json { "metrics": [ { "properties": { "values": [ {"int_value": 99}, { "propertyset_value": { "values": [{"int_value": 999}], "keys": ["inner"] } }, { "propertysets_value": { "propertyset": [ { "values": [{"int_value": 1}], "keys": ["inner1"] }, { "values": [{"int_value": 2}], "keys": ["inner2"] } ] } } ], "keys": [ "leaf", "nested_prop", "nested_prop_list" ] } }, { "dataset_value": { "num_of_columns": 2, "types": [7, 12], "rows": [ { "elements": [ {"int_value": 3}, {"string_value": "3"} ] }, { "elements": [ {"int_value": 4}, {"string_value": "4"} ] } ], "columns": ["col1", "col2"] } } ] }

Then, the output of spb_zip_kvs will be:

json { "metrics": [ { "properties": { "nested_prop_list": { "propertysets_value": [ {"inner1": {"int_value": 1}}, {"inner2": {"int_value": 2}} ] }, "nested_prop": { "propertyset_value": {"inner": {"int_value": 999}} }, "leaf": {"int_value": 99} } }, { "dataset_value": { "col2": {"elements": [{"int_value": 4}, {"string_value": "4"}]}, "col1": {"elements": [{"int_value": 3}, {"string_value": "3"}]} } } ] }

REST API

  • #16718 Improve REST API Swagger spec.

Previously, summaries and descriptions of spec fields were mixed together. Now, summaries are brief, simple and punctuation-free, while descriptions provide all the details.

  • #16735 EMQX now supports plugin-defined HTTP API callbacks under /api/v5/plugin_api/{plugin}/....

This allows plugin authors to expose plugin-specific API endpoints through the dashboard API service, with consistent authentication and HTTP error handling.

Observability

  • #16656 Made system monitor reports such as busy_port and long_schedule more informative by including process labels for easier troubleshooting.

  • #16744 Supports end-to-end tracing of messages published via HTTP API.

Performance

  • #16413 Improve subscription handling performance.

  • #16492 Slightly improve idle system memory usage.

  • #16757 Set os_mon to collect only system-wide memory statistics by default, reducing per-process memory scanning overhead.

Bug Fixes

Core MQTT Functionalities

  • #16480 Fixed an issue where WebSocket connections could crash after the peer closed the connection, typically observed under moderate load.

crasher: initial call: cowboy_tls:connection_process/4, error: {{case_clause,{error,closed}},[ {cowboy_websocket_linger,websocket_send_close,2,[{file,"cowboy_websocket_linger.erl"},{line,752}]}, {cowboy_websocket_linger,websocket_close,3,[{file,"cowboy_websocket_linger.erl"},{line,743}]}, {proc_lib,wake_up,3,[{file,"proc_lib.erl"},{line,340}]} ]} messages: [ {ssl,{sslsocket,{gen_tcp,#Port<...>,...},[...]},<<130,130,27,93,145,101,251,93>>}, {ssl_closed,{sslsocket,{gen_tcp,#Port<...>,...},[...]}} ], ...

  • #16515 Fixed a bug that caused WebSocket connections to crash when receiving broker messages larger than the client's advertised Maximum-Packet-Size.

  • #16553 Fixed an issue where not all retained messages would be delivered if a subscriber hit the retained message dispatch rate limit.

If the dispatch rate limit is reached while iterating over retained topics, then the client process will retry the iteration at a later time with exponential back-off (minimum 300 ms, maximum 10 s).

The retainer.flow_control.batch_deliver_number configuration has been deprecated. The retainer.flow_control.batch_read_number no longer supports being set to 0 to mean read all remaining retained messages at once. If set to 0, it'll default to 1000 messages.

  • #16569 Fixed a rare race condition that could cause the supporting emqx_flapping process for flapping detection to crash under high system load.

  • #16651 Fixed a rare connection process crash during shutdown caused by operating on an already closed socket, typically under high system stress. Prior to this fix, such race condition typically result in an error level log saying {badmatch,{ok,{sock_error,closed}....

  • #16675 Fixed timestamp ordering issue where disconnected_at could be later than connected_at during session takeover or discard scenarios.

Previously, disconnected_at was recorded too late (in ensure_disconnected), after the new session's connected_at was already set. This caused a race condition where disconnected_at > connected_at, making it difficult to track client presence state externally.

The fix records disconnected_at immediately when takeover begins or when discard is received, ensuring it's always earlier than the new session's connected_at. This ensures correct timestamp ordering for external presence state tracking systems.

  • #16715 Fixed an issue where retained $SYS messages (for example, broker/node identity topics) were stored without expiry, which could leave stale node identifiers visible in Dashboard views after StatefulSet rotation.

Now, newly published retained $SYS messages include Message-Expiry-Interval = 3600 (1 hour).

For already existing stale retained $SYS entries created before this change, you can manually clear them by publishing an empty retained message to the stale topic:

bash emqx eval 'emqx:publish(emqx_message:set_flag(retain, true, emqx_message:make(emqx_sys, <<"$SYS/brokers/emqx@127.0.0.1/sysdescr">>, <<>>))).'

Replace the topic in the command with the stale $SYS/... topic you want to remove.

  • #16731 Fixed a crash in emqx ctl subscriptions list that could happen when shared subscriptions were present.

Before this fix, listing subscriptions could fail for some clients and return no output.

After this fix, emqx ctl subscriptions list works reliably with both regular and shared subscriptions.

  • #16782 Fixed MQTT v5 protocol handling for invalid PUBLISH properties.

If a client sends a PUBLISH packet containing Subscription-Identifier, EMQX now treats it as a protocol error and disconnects the client.

Gateway

  • #16603 Fixed the CoAP Gateway when running in DTLS connection mode.

  • #16670 NATS gateway now enforces the max publish payload, honors the echo option (no local delivery), and improves publish/subscribe subject handling and related error messages.

Access Control

  • #16423 Added support for verifying the 'aud' (audience) claim in JWT authentication.

When the 'aud' claim is configured in verify_claims, the JWT token must include a valid 'aud' claim. The verification supports both string and array formats:

  • If 'aud' is a string, it must exactly match the expected value.
  • If 'aud' is an array, at least one element in the array must match the expected value.
  • Empty string or empty array will fail verification.
  • Missing 'aud' claim will fail verification when it's configured in verify_claims.

  • #16459 Fixed the issue in SCRAM authentication HTTP API. Previously, incorrect user ID was returned for the created user in the user creation API call.

Data Integration

  • #16507 Previously, when an MQTT Source's Connector recovered after losing its connection, topics would not be re-subscribed and the Source would stop working until the Connector itself was restarted. Now, the Source will re-subscribe upon reconnect.

  • #16542 Fixed an issue where Kafka producer connections could disconnect prematurely when Kafka was overloaded, causing excessive produce request retries. The request timeout is now automatically set to at least twice the metadata request timeout (with a minimum of 30 seconds), reducing unnecessary reconnections and retries when metadata requests take longer than expected. This is especially beneficial when metadata request timeout is configured to a small value.

  • #16622 Fixed an issue where, if an Action used async query mode and its Connector was disconnect after more than one health check, its Fallback Actions could be triggered twice.

  • #16657 Fixed an issue where, when importing configuration from an older node version into a newer one, values would not be upgraded according to newer code, leading to strange behavior.

One such example is importing a MQTT Connector with static clientids from 5.10.0 into 6.0.0. In 5.10.0, usernames and passwords could not be associated with particular static clientids, and this was represented internally in a certain way. Later versions added the capability of creating those associations, with a different internal representation. This subtle internal representation conversion was missing when importing such configurations in previous EMQX versions.

  • #16659 When using an older MQTT Connector configuration with static clientids (from 5.10.0 and earlier) on later EMQX versions, the username and password at the root of the configuration was ignored. This could cause trouble when upgrading and keeping the same configuration, as the MQTT clients would stop using the credentials.

Now, if there are username and/or password fields in the root Connector, those credentials are merged with any specific ones specified per clientid, the latter taking precedence.

  • #16723 Fixed an issue with RabbitMQ Connector/Action/Source where, if some connection or channel processes died unexpectedly, the Connector/Action/Source would be reported as disconnected and never recover by itself without restarting it.

  • #16742 Fixes the issue of GreptimeDB TLS connection failure.

Durable Storage

  • #16512 Improve handling of recoverable errors in the durable session. Durable sessions will now retry creation of durable storage iterators when that operation fails due to network issue. Previously, the whole session would get disconnected.

Fix problem with the retry mechanism in the emqx_ds_client component. Previously, the number of retry attempts on recoverable errors was limited.

Fix problems with the shared subscriptions:

  • Fix problem with shared subscription leader not coming up after node restart.
  • Shared subscription leader no longer advertises streams that reached the end of replay to the clients.
  • Make shared sub leader state checkpoint transaction options configurable

  • #16614 Improvements and bug fixes related to durable storage feature.

  • Improved handling of configuration inconsistencies between the nodes.

    Previously, when a durable storage was created in a cluster where nodes had different initial durable storage configuration, the replicas wound not converge. This change addresses this problem by replicating the configuration of the shard leader node to the replicas during initialization of the storage and subsequent configuration changes.

    Warning: this change is not backward-compatible. During a rolling cluster upgrade the shards will pause until the majority of their replicas are upgraded to the new version of EMQX, after which downgrade to the previous versions of EMQX will become impossible.

  • Fixed an issue in the durable storage subscription mechanism.

    Previously, a durable subscription created with a fresh iterator could miss a stored message with the timestamp precisely matching timestamp of the iterator.

  • #16770 Improve stability of durable sessions during takeover and garbage collection.

Clustering

  • #16393 Improved the stability of the Cluster Link route replication under unstable network conditions.

  • #16465 Upgraded gen_rpc to 3.5.1.

Prior to the gen_rpc upgrade, EMQX may experience long tail of crash logs due to connect timeout if a peer node is unreachable. The new version gen_rpc no longer has the long tail and converted crash logs to more readable error logs, and the frequent log "failed_to_connect_server" is also throttled to avoid spamming.

  • #16544 Improve robustness of cluster autoclean procedure.

Previously, if autoclean feature was disabled during initial start of the node, it would never activate after configuration change. This fix resolves this issue.

  • #16739 Improved recovery time of a cluster after a simultaneous restart of all nodes.

Built-in Mria database management system no longer waits for the full sync of an internal table used to generate transaction synchronization events.

Observability

  • #16537 Fixed formatter crash when logging gen_rpc errors.

Prior to this fix, EMQX may report "FORMATTER CRASH" errors when gen_rpc logged certain error messages (e.g., transmission timeout errors). The formatter now handles these error messages correctly without crashing.

  • #16661 Improve topic_metrics and cluster_rpc logging when invalid topic is requested.

  • #16674 Ensure Erlang pid is printed as a log data field.

  • #16699 Previously, under certain race conditions, long and cryptic logs like the following could be printed:

2026-02-03T13:53:54.576326+00:00 [error] Generic server <0.11323236.0> terminating. Reason: {{badkey,'actions.success'},[{erlang,map_get,['actions.success',#{}],[{error_info,#{module => erl_erts_errors}}]},{emqx_metrics_worker,idx_metric,4,[{file,"emqx_metrics_worker.erl"},{line,683}]},{emqx_metrics_worker,inc,4,[{file,"emqx_metrics_worker.erl"},{line,322}]},{emqx_rule_runtime,do_eval_action_reply_t...

Now, we print more meaningful information to help debug the issue.

Security

  • #16545 Fixed node.cookie handling of # character. Previously, if the cookie contained #, only the prefix before # would take effect. For example, if abc#d was configured, only abc was used as the cookie.

Added validation to reject problematic characters: backslash, single quote, double quote, and space.

  • #16664 Previously, it was possible to upload managed certificate files associated with non-existent managed namespaces. Now, namespace existence is checked before accepting the upload.

  • #16692 Fixed a CRL cache regression where emqx_crl_cache:evict/1 did not fully clear internal URL state. After eviction, the same CRL URL now re-registers correctly on next use, restores its refresh timer, and avoids repeated HTTP fetches per connection.

Plugin

  • #16784 Reduced noisy plugin startup warnings in single-node deployments.

EMQX no longer tries to fetch plugin config from the local node during cluster config sync, avoiding repeated config_not_found_on_node warnings at startup.

  • #16823 Fixed a Dashboard plugin management issue for preinstalled plugins.

When a plugin package is unpacked into plugins/ before node startup, starting it from the Dashboard no longer causes Plugin Config Not Found on the plugin config page.

Miscellaneous

  • #16620 Fix CRC32C dynamic library load issue on aarch64.
Source: README.md, updated 2026-02-26