MQTTnet
MQTTnet copied to clipboard
Server error when using TLS 1.2: CONNECT packet must have at least 7 bytes
When connecting to the MQTT Server with TLS, the following error is thrown:
[20:57:49 Debug Apm-Trace: Apm-Transaction:] Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
Connection id "0HMVPO9R8V5EA" communication error.
MQTTnet.Exceptions.MqttProtocolViolationException: **CONNECT packet must have at least 7 bytes.**
at MQTTnet.Formatter.MqttPacketFormatterAdapter.ParseProtocolVersion(ReceivedMqttPacket receivedMqttPacket)
at MQTTnet.Formatter.MqttPacketFormatterAdapter.DetectProtocolVersion(ReceivedMqttPacket receivedMqttPacket)
at MQTTnet.AspNetCore.ReaderExtensions.TryDecode(MqttPacketFormatterAdapter formatter, ReadOnlySequence`1& input, MqttPacket& packet, SequencePosition& consumed, SequencePosition& observed, Int32& bytesRead)
at MQTTnet.AspNetCore.MqttConnectionContext.ReceivePacketAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketConnection.DoSend()
at MQTTnet.Server.MqttClientSessionsManager.ReceiveConnectPacket(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
at MQTTnet.Server.MqttClientSessionsManager.HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
[20:57:49 Debug Apm-Trace: Apm-Transaction:] Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
Connection id "0HMVPO9R8V5EA" sending RST because: "CONNECT packet must have at least 7 bytes."
Which component is your bug related to?
- .net8.0
- Client - MQTTnet 4.3.3.952
- Server - MQTTnet 4.3.3.952 and MQTTnet.AspNetCore 4.3.3.952 Note: this works with a server that is version 3.x
Client Code example
var currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var certificate = new X509Certificate2(Path.Combine(currentPath, "certificate.pfx"), "password-redacted", X509KeyStorageFlags.Exportable);
// Create a new MQTT client.
var factory = new MqttFactory();
mqttClient = factory.CreateMqttClient();
var options = new MqttClientOptionsBuilder()
.WithClientId(clientId)
.WithTcpServer("localhost", 8883)
.WithTlsOptions(o =>
{
o.UseTls(true);
o.WithClientCertificates(new List<X509Certificate2> { certificate });
o.WithCertificateValidationHandler(_ => true);
o.WithAllowUntrustedCertificates(true);
o.WithIgnoreCertificateChainErrors(true);
o.WithIgnoreCertificateRevocationErrors(true);
// the default value is determined by the os. set manually to force version.
o.WithSslProtocols(SslProtocols.Tls12);
})
.WithCredentials(username, password)
.WithCleanSession()
.Build();
await mqttClient.ConnectAsync(options, CancellationToken.None); //server crashes when the client reaches this line
Using v4.2.1.781 of the library.
I have a customer seeing a similar issue, but I am not able to reproduce the issue in a local test bed (also using TLS). I suspect there is something on the network causing issues, but that is just a guess. Here is the stack I currently have:
Here are the stacks I see from both sides:
20:25:47.226] Broker: CONNECT packet must have at least 7 bytes. Exception:MQTTnet.Exceptions.MqttProtocolViolationException: CONNECT packet must have at least 7 bytes. at MQTTnet.Formatter.MqttPacketFormatterAdapter.ParseProtocolVersion(ReceivedMqttPacket receivedMqttPacket) at MQTTnet.Adapter.MqttChannelAdapter.<ReceivePacketAsync>d__36.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MQTTnet.Server.MqttClientSessionsManager.<ReceiveConnectPacket>d__30.MoveNext()
[20:25:47.248] Broker: Error while handling TCP client connection Exception:System.IO.IOException: The handshake failed due to an unexpected packet format. at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MQTTnet.Implementations.MqttTcpServerListener.<TryHandleClientConnectionAsync>d__16.MoveNext()
If the client and server communicate without TLS, there are no issues.
Also note we are using the ManagedClient.
For what it is worth, I had my customer disable TLS and the 'CONNECT packet must have at least 7 bytes.' error is still being seen from time to time.
This is still an issue in v4.3.6.1152
Stack trace:
MQTTnet.Exceptions.MqttProtocolViolationException: CONNECT packet must have at least 7 bytes. at MQTTnet.Formatter.MqttPacketFormatterAdapter.ParseProtocolVersion(ReceivedMqttPacket receivedMqttPacket) at MQTTnet.Formatter.MqttPacketFormatterAdapter.DetectProtocolVersion(ReceivedMqttPacket receivedMqttPacket) at MQTTnet.AspNetCore.ReaderExtensions.TryDecode(MqttPacketFormatterAdapter formatter, ReadOnlySequence``1& input, MqttPacket& packet, SequencePosition& consumed, SequencePosition& observed, Int32& bytesRead) at MQTTnet.AspNetCore.MqttConnectionContext.ReceivePacketAsync(CancellationToken cancellationToken) at MQTTnet.Server.MqttClientSessionsManager.ReceiveConnectPacket(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken) at MQTTnet.Server.MqttClientSessionsManager.HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
@chkr1011 any thoughts?
@ovidiaconescu
This issue seems to occur when TLS decryption isn't set up correctly. I was trying to use a custom ICertificateProvider because my root CA and intermediate broker certificate were unavailable during the configuration of my .NET 8 backend.
Unfortunately, I couldn't get it to work. As a workaround, I added UseHttps to my Kestrel configuration to handle the decryption, followed by UseMqtt to add the MqttConnectionHandler.