AWS Developer Tools Blog
AWS IoT Device SDK MQTT 3.1.1 and V1 Service Clients Entering Maintenance Mode
In alignment with our AWS SDKs and Tools maintenance policy, the AWS IoT Device SDKs MQTT 3.1.1 and V1 service clients will enter maintenance mode in April 2027. There is no planned end-of-support date, and we will announce any change to that separately.
We recommend that you adopt the MQTT 5 client and V2 service clients, which provide a more robust feature set, clearer error handling, and lifecycle management. Future feature development will target the MQTT 5 and V2 service clients.
The migrations for MQTT client and service clients are independent. V2 service clients work with both MQTT 3.1.1 and MQTT5 clients, so you can upgrade the service clients and the MQTT client separately, on your own schedule.
Impact
The MQTT 3.1.1 client and V1 service clients are fully supported until April 2027. After that, releases are limited to critical bug fixes and security issues. We have no plans to remove them from the AWS IoT Device SDKs and AWS Common Runtime (CRT) libraries, so your existing applications continue to work
The impacted libraries and SDKs are the following.
- aws-crt-cpp
- aws-crt-java
- aws-crt-nodejs
- aws-crt-python
- aws-iot-device-sdk-cpp-v2
- aws-iot-device-sdk-java-v2
- aws-iot-device-sdk-js-v2
- aws-iot-device-sdk-python-v2
Benefits of Migrating to MQTT5
The MQTT5 client provides substantial improvements over the MQTT3 client:
- Full MQTT5 protocol support — Gain access to modern MQTT5 features including reason codes on all ACKs, message expiry, and user properties.
- Improved reliability and reconnection — The MQTT5 client automatically reconnects and provides a configurable offline operations queue for messages sent while disconnected.
- Better observability — Richer lifecycle events, detailed reason codes on errors, and operation statistics tracking make debugging and monitoring easier.
- Modernized service clients — The v2 service clients introduced a request-response based usage pattern that simplifies interactions with AWS IoT services like AWS IoT Jobs, AWS IoT Device Shadow, and AWS IoT Fleet Provisioning.
Migration Guidance
You can refer to the language-specific MQTT5 User Guides for complete details and equivalent code:
- MQTT5 User Guide – C++
- MQTT5 User Guide – Java
- MQTT5 User Guide – JavaScript
- MQTT5 User Guide – Python
Migrating from the MQTT 3.1.1 client to the MQTT 5 client touches four areas: creating the client, handling lifecycle events, starting and stopping the client, and client operations. The following code examples show migration steps using AWS IoT Device SDK for Java, but the same concepts and migration patterns apply to AWS IoT Device SDK for C++, AWS IoT Device SDK for Python, and AWS IoT Device SDK for JavaScript.
Client Creation
Use the client builder AwsIotMqtt5ClientBuilder to create the MQTT5 client. The MQTT5 builder supports the same connection methods (mTLS, WebSocket/SigV4, Custom Authorizer, PKCS#11, PKCS#12, Java Keystore, etc.) as the MQTT3 builder, with a consistent API.
// Before (MQTT3)
AwsIotMqttConnectionBuilder builder = AwsIotMqttConnectionBuilder.newMtlsBuilderFromPath(certPath, keyPath);
builder.withClientId(clientId)
.withEndpoint(endpoint);
MqttClientConnection connection = builder.build();
builder.close();
// After (MQTT5)
// Use the builder to set up client options
AwsIotMqtt5ClientBuilder builder = AwsIotMqtt5ClientBuilder.newDirectMqttBuilderWithMtlsFromPath(
endpoint, certPath, keyPath);
builder.withClientId(clientId);
Mqtt5Client client = builder.build(); // Build the client
builder.close(); // Clean up the resource
Lifecycle Events
Replace MqttClientConnectionEvents with Mqtt5ClientOptions.LifecycleEvents. The MQTT5 client provides five lifecycle events with richer information:
// Before (MQTT3)
MqttClientConnectionEvents callbacks = new MqttClientConnectionEvents() {
@Override
public void onConnectionInterrupted(int errorCode) { }
@Override
public void onConnectionResumed(boolean sessionPresent) { }
};
// After (MQTT5)
// Setup lifecycle event callbacks. The callbacks run when the client state changes.
Mqtt5ClientOptions.LifecycleEvents lifecycleEvents = new Mqtt5ClientOptions.LifecycleEvents() {
// Called when the client begins a connection attempt
@Override
public void onAttemptingConnect(Mqtt5Client client, OnAttemptingConnectReturn onAttemptingConnectReturn) {
System.out.printf("Lifecycle Connection Attempt%nConnecting to endpoint: '%s' with client ID '%s'%n",args.endpoint, args.clientId);
}
// Called when the client successfully establishes an MQTT connection
@Override
public void onConnectionSuccess(Mqtt5Client client, OnConnectionSuccessReturn onConnectionSuccessReturn) {
System.out.println("Lifecycle Connection Success with reason code: " +
onConnectionSuccessReturn.getConnAckPacket().getReasonCode() + "\n");
}
// Called when the client fails to establish an MQTT connection
@Override
public void onConnectionFailure(Mqtt5Client client, OnConnectionFailureReturn onConnectionFailureReturn) {
System.out.println("Lifecycle Connection Failure with error code: " +
onConnectionFailureReturn.getErrorCode());
}
// Called when the client's current MQTT connection is closed
@Override
public void onDisconnection(Mqtt5Client client, OnDisconnectionReturn onDisconnectionReturn) {
System.out.println("Mqtt5 Client: Disconnected");
DisconnectPacket disconnectPacket = onDisconnectionReturn.getDisconnectPacket();
if (disconnectPacket != null) {
System.out.println("\nDisconnection packet code: " + disconnectPacket.getReasonCode() +
"\nDisconnection packet reason: " + disconnectPacket.getReasonString());
}
}
// Called when the client reaches the 'Stopped' state after you call client.stop()
@Override
public void onStopped(Mqtt5Client client, OnStoppedReturn onStoppedReturn) {
System.out.println("Lifecycle Stopped\n");
}
};
Use start()/stop()
Replace connection.connect() / connection.disconnect() with client.start() / client.stop(). The MQTT5 client automatically reconnects until stop() is called.
// Before (MQTT3)
connection.connect();
connection.disconnect();
connection.close();
// After (MQTT5)
client.start(); // Start Connection
client.stop(); // Stop Connection
client.close(); // Clean up the resource to avoid memory leak
Client Operations
Replace MqttClientConnection.publish() with the MQTT5 packet-based publish API. The MQTT5 client returns a PubAckPacket with reason codes for QoS 1 publishes.
// Before (MQTT3)
connection.publish(new MqttMessage(topic, payload.getBytes()), QualityOfService.AT_LEAST_ONCE, false).get();
// After (MQTT5)
// Packet-based publish lets you build the packet once and reuse it across multiple publish() calls.
PublishPacket publishPacket = PublishPacket.of(topic, QOS.AT_LEAST_ONCE, payload.getBytes());
// Publish operation. For QoS 1, the future resolves to a PubAckPacket that contains reason code. Use the reason code to distinguish success from different errors.
PubAckPacket pubAck = client.publish(publishPacket).get().getResultPubAck();
Code Examples
Documentation and samples for the MQTT 5 and V2 service clients are available in the respective GitHub repositories.
- aws-iot-device-sdk-cpp-v2 Samples
- aws-iot-device-sdk-java-v2 Samples
- aws-iot-device-sdk-js-v2 Samples
- aws-iot-device-sdk-python-v2 Samples
Conclusion
In this post, we announced that the MQTT 3.1.1 client and V1 service clients will enter maintenance mode in April 2027 across the AWS IoT Device SDKs and CRT libraries. We encourage all customers to begin planning their migration to the MQTT5 client to take advantage of improved reliability, richer protocol features, better error handling, and modernized service client patterns.
If you have questions or need assistance, reach out through GitHub Issues or Discussions in the respective SDK repository:
- AWS IoT Device SDK C++ v2 — Issues | Discussions
- AWS IoT Device SDK Java v2 — Issues | Discussions
- AWS IoT Device SDK JavaScript v2 — Issues | Discussions
- AWS IoT Device SDK Python v2 — Issues | Discussions