TLS Initialization Failed on MacOS in Deployed Application
-
Got an interesting issue that I am trying to track down. Our application talks to our web server through “https” which uses SSL at some point. We are using Qt 6.7 and Qt 6.8 on macOS (where this problem is occurring). If I build and run from my IDE (CLion) everything works just fine. When I create the final deployable .app package and then try the same operation I get the “TLS Initialization Failed”.
I have looked in the .app package at the Plugins folder which does contain the “tls” subdirectory and there are 3 libraries inside that folder. Adding these 3 plugins solved the issue on the other platforms (Linux and Windows) but macOS I guess is missing something “special”. Anyone have any ideas what special sauce I need for my macOS package? We are using the Qt binaries downloaded from Qt.io. Feel like I’m missing an openssl library maybe?
I’ve tested on both ARM64 and x64 systems running macOS 14.7.4.
Thanks for any help.
Mike Jackson -
Hi,
You will also need to update the rpath of the plugins so they search for their non system dependencies within the bundle. You can do that with otool (the check) and install_name_tool (the paths changes).
-
@SGaist Yep. that is done during the deployment process.
1005:[mjackson@Octane:tls]% otool -L libqopensslbackend.dylib libqopensslbackend.dylib (architecture x86_64): /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1953.255.0) /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 60420.60.24) @rpath/QtNetwork.framework/Versions/A/QtNetwork (compatibility version 6.0.0, current version 6.7.3) @rpath/QtCore.framework/Versions/A/QtCore (compatibility version 6.0.0, current version 6.7.3) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1300.36.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0) libqopensslbackend.dylib (architecture arm64): /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1953.255.0) /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 60420.60.24) @rpath/QtNetwork.framework/Versions/A/QtNetwork (compatibility version 6.0.0, current version 6.7.3) @rpath/QtCore.framework/Versions/A/QtCore (compatibility version 6.0.0, current version 6.7.3) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1300.36.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0) -
I guess it would be handy to know exactly which OpenSSL library is trying to be loaded via DLOpen().
-
For OpenSSL, it's should be the 3 series looking at your Qt versions.
-
Is that something that I, as the app developer, should be compiling and including in my app package?
The weird thing is that it works if I just launch the app from my IDE, but when I package then it fails. This leads me to believe that the the necessary libraries are in the Qt install but are not getting included in my package.
-
I think it's likely rather something that should be fixed at the macdeployqt level.
-
More debugging: When I run my app from the IDE I get this:
Debug: QSslSocket::supportsSsl(): true QSslSocket::sslLibraryBuildVersionString(): "Secure Transport, macOS Sonoma (14.7)" QSslSocket::sslLibraryVersionString(): "Secure Transport, macOS Sonoma (14.7)"After packaging I get:
Warning: No functional TLS backend was found Warning: No functional TLS backend was found Debug: QSslSocket::supportsSsl(): false QSslSocket::sslLibraryBuildVersionString(): "" QSslSocket::sslLibraryVersionString(): "" Warning: No functional TLS backend was found Warning: No functional TLS backend was found Warning: QSslSocket::connectToHostEncrypted: TLS initialization failed -
About the only difference I can see is that CMake likes to use @executable_path instead of @rpath in the libraries. Not really sure what it could be past that. I tured off the CMake install bits, and basically rewrote the logic for macdeployqt to look for additional libraries that I know are not being picked up with macdeployqt. Seems like I've probably reinvented the wheel but not sure what else to do to solve the problem. I now have a working macOS DMG package that can properly initialize TLS and talk to our https web server.
-
I guess it would be handy to know exactly which OpenSSL library is trying to be loaded via DLOpen().
@imikejackson said in TLS Initialization Failed on MacOS in Deployed Application:
I guess it would be handy to know exactly which OpenSSL library is trying to be loaded via DLOpen().
The environment variable QT_DEBUG_PLUGINS is a good first step for debugging any dynamic library use by Qt-using applications. I ran a quick test program with TLS support on a mac, and found the output to be under-informative. It's still my first suggestion.
Setting DYLD_PRINT_SEARCHING resulted in more useful information, for this case, about attempts to locate libssl and others. For example:
dyld[24496]: find path "/usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib" dyld[24496]: possible path(original path): "/usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib" dyld[24496]: found: dylib-from-disk: "/usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib"The
man -S 1 dyldsuggests several other environment variables to try.