Given a simple test application that simply calls WinHttpOpen()
as follows and does nothing else:
WinHttpOpen(userAgent, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC | WINHTTP_FLAG_SECURE_DEFAULTS);
I've noticed that the above call fails with error code 87 (ERROR_INVALID_PARAMETER
) on Windows Server 2019 (Datacenter or Standard) and older machines (also tested on Windows Server 2016 Standard). It works as expected on Windows 10 Enterprise and Windows Server 2022 Datacenter.
Removing the WINHTTP_FLAG_SECURE_DEFAULTS
flag makes the issue go away. As this flag enforces TLS 1.2 or newer, it seems likely that there's some OS-level configuration needed. (Note that this doesn't impact SChannel use of TLS 1.2).
Is there some registry configuration, feature, or patch that is generally missing on Windows Server 2019 and older installations?
WINHTTP_FLAG_SECURE_DEFAULTS
simply didn't exist on older systems, so if you try to use it on them, they won't know what that flag means, and so they will fail. This is even called out explicitly in Microsoft's documentation:
Game Development Kit (GDK) | Overviews and how-to | Networking | Web requests | WinHTTP overview
The
WINHTTP_FLAG_SECURE_DEFAULTS
flag is a new flag that's specifically designed to help Microsoft Game Development Kit (GDK) titles to adhere to the security best practices by setting the recommended secure connection behavior. It's available on Xbox One consoles and will be available on Windows PC in a future Windows OS update. Trying to passWINHTTP_FLAG_SECURE_DEFAULTS
on existing Windows OS versions results in an invalid parameter failure. This flag has a significant side effect—it forces WinHTTP into the asynchronous mode because this flag implicitly includes theWINHTTP_FLAG_ASYNC
flag. On Windows PC OS versions that don't support this flag, you should passWINHTTP_FLAG_ASYNC
instead to minimize differences in the remainder of your WinHTTP implementation.