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.

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:

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.

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:

Additional Resources

Vera Xia

Vera Xia

Vera Xia is a software engineer on the AWS SDK Performance team, where she builds and maintains the AWS IoT Device SDK and focuses on performance and reliability across the AWS SDKs.

Steve Kim

Steve Kim

Software Engineer working within the AWS SDKs and Tools org.