diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp
index 64d5e4c7ef78108eca57dea52f725780311a6a17..b9c6cc032ca6cc254d7d94bed84a78e361c08a36 100644
--- a/src/websockets/qwebsocket.cpp
+++ b/src/websockets/qwebsocket.cpp
@@ -402,7 +402,10 @@ qint64 QWebSocket::sendBinaryMessage(const QByteArray &data)
 
     Any data in the write buffer is flushed before the socket is closed.
     The \a closeCode is a QWebSocketProtocol::CloseCode indicating the reason to close, and
-    \a reason describes the reason of the closure more in detail
+    \a reason describes the reason of the closure more in detail. All control
+    frames, including the Close frame, are limited to 125 bytes. Since two of
+    these are used for \a closeCode the maximum length of \a reason is 123! If
+    \a reason exceeds this limit it will be truncated.
  */
 void QWebSocket::close(QWebSocketProtocol::CloseCode closeCode, const QString &reason)
 {
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp
index 45d6a6f40135f1d59852cb7dd55eb89672afd5bc..9b27ad21a130ca917501ddaedd6906413e686b07 100644
--- a/src/websockets/qwebsocket_p.cpp
+++ b/src/websockets/qwebsocket_p.cpp
@@ -334,12 +334,14 @@ void QWebSocketPrivate::close(QWebSocketProtocol::CloseCode closeCode, QString r
     if (!m_isClosingHandshakeSent) {
         Q_Q(QWebSocket);
         m_closeCode = closeCode;
-        m_closeReason = reason;
+        // 125 is the maximum length of a control frame, and 2 bytes are used for the close code:
+        const QByteArray reasonUtf8 = reason.toUtf8().left(123);
+        m_closeReason = QString::fromUtf8(reasonUtf8);
         const quint16 code = qToBigEndian<quint16>(closeCode);
         QByteArray payload;
         payload.append(static_cast<const char *>(static_cast<const void *>(&code)), 2);
-        if (!reason.isEmpty())
-            payload.append(reason.toUtf8());
+        if (!reasonUtf8.isEmpty())
+            payload.append(reasonUtf8);
         quint32 maskingKey = 0;
         if (m_mustMask) {
             maskingKey = generateMaskingKey();
@@ -347,6 +349,8 @@ void QWebSocketPrivate::close(QWebSocketProtocol::CloseCode closeCode, QString r
         }
         QByteArray frame = getFrameHeader(QWebSocketProtocol::OpCodeClose,
                                           payload.size(), maskingKey, true);
+
+        Q_ASSERT(payload.length() <= 125);
         frame.append(payload);
         m_pSocket->write(frame);
         m_pSocket->flush();
diff --git a/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp b/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
index e80eeb100114667c7522c54853f0b0ed3a26280b..4dc60c74d10f5d170319418f80bb6f98633dee1e 100644
--- a/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
+++ b/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
@@ -143,6 +143,7 @@ private Q_SLOTS:
 #ifndef QT_NO_NETWORKPROXY
     void tst_setProxy();
 #endif
+    void overlongCloseReason();
 };
 
 tst_QWebSocket::tst_QWebSocket()
@@ -732,6 +733,34 @@ void tst_QWebSocket::tst_setProxy()
     socket.setProxy(proxy);
     QCOMPARE(socket.proxy(), proxy);
 }
+
+void tst_QWebSocket::overlongCloseReason()
+{
+    EchoServer echoServer;
+
+    QWebSocket socket;
+
+    //should return 0 because socket is not open yet
+    QCOMPARE(socket.sendTextMessage(QStringLiteral("1234")), 0);
+
+    QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected()));
+    QSignalSpy socketDisconnectedSpy(&socket, SIGNAL(disconnected()));
+    QSignalSpy serverConnectedSpy(&echoServer, SIGNAL(newConnection(QUrl)));
+
+    QUrl url = QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() +
+                    QStringLiteral(":") + QString::number(echoServer.port()));
+    socket.open(url);
+    QTRY_COMPARE(socketConnectedSpy.count(), 1);
+    QTRY_COMPARE(serverConnectedSpy.count(), 1);
+
+    const QString reason(200, QChar::fromLatin1('a'));
+    socket.close(QWebSocketProtocol::CloseCodeGoingAway, reason);
+    QCOMPARE(socket.closeCode(), QWebSocketProtocol::CloseCodeGoingAway);
+    // Max length of a control frame is 125, but 2 bytes are used for the close code:
+    QCOMPARE(socket.closeReason().length(), 123);
+    QCOMPARE(socket.closeReason(), reason.leftRef(123));
+    QTRY_COMPARE(socketDisconnectedSpy.count(), 1);
+}
 #endif // QT_NO_NETWORKPROXY
 
 QTEST_MAIN(tst_QWebSocket)