Skip to content

HttpClient.UseServerCertificateValidation(false) invalidates previously obtained DefaultRequestHeaders reference and causes headers to be lost #8172

@jasperboot

Description

@jasperboot

1. Describe the bug

When using HttpClient.UseServerCertificateValidation(false) in AL, the call appears to replace the internal HttpHeaders list on the HttpClient handler, causing the previously retrieved HttpHeaders reference from HttpClient.DefaultRequestHeaders() to become invalid (although you won't notice it!).

As a result, any custom headers added to this list (gotten BEFORE calling UseServerCertificateValidation(false)) are silently dropped and not sent with the request.

The only workaround is to call:

Client.UseServerCertificateValidation(false);
Headers := Client.DefaultRequestHeaders();

in this order.

This behavior is undocumented and unexpected, and it breaks scenarios where:

  • custom headers are required for routing (e.g., Ocelot, API gateways)
  • custom authentication headers are added before enabling certificate validation override
  • headers are added in helper procedures before the validation mode is set

2. To Reproduce

Steps to reproduce the behavior:

Case 1 ΓÇö Headers reference gotten BEFORE disabling certificate validation (fails)

procedure TestHttpClient()
var
    Client: HttpClient;
    Headers: HttpHeaders;
    Response: HttpResponseMessage;
begin
    // 1. Get default headers object BEFORE disabling cert validation
    Headers := Client.DefaultRequestHeaders();

    // 2. Disable certificate validation
    Client.UseServerCertificateValidation(false);

    // 3. Manipulate the headers
    Headers.Add('X-Test-Header', '123');
    
    // 4. Send a request
    Client.Get('https://example.com', Response);

    // On the receiving server:
    // --> X-Test-Header is NOT present
end;

Case 2 ΓÇö Headers reference gotten AFTER disabling certificate validation (works)

procedure TestHttpClientFixed()
var
    Client: HttpClient;
    Headers: HttpHeaders;
    Response: HttpResponseMessage;
begin
    // 1. Disable certificate validation FIRST
    Client.UseServerCertificateValidation(false);

    // 2. Get default headers
    Headers := Client.DefaultRequestHeaders();
    
    // 3. Manipulate the headers
    Headers.Add('X-Test-Header', '123');

    // 4. Send a request
    Client.Get('https://example.com', Response);

    // On the receiving server:
    // --> X-Test-Header IS present
end;

3. Expected behavior

HttpClient.UseServerCertificateValidation(false) should not invalidate previously obtained references to DefaultRequestHeaders, nor should it silently remove custom headers already added.

Headers added via:

Headers := Client.DefaultRequestHeaders();
Headers.Add('X-MyHeader', 'value');

should remain attached to the HttpClient instance regardless of when certificate validation mode is changed.

OR, at the very minimum, this should be documented very well in the documentation for UseServerCertificateValidation

4. Actual behavior

  • After calling UseServerCertificateValidation(false), the previous DefaultRequestHeaders instance becomes invalid.
  • Custom headers added before calling the method are lost and not included in the request.
  • No warning or error is raised.
  • Behavior silently changes based on call order.

4b. Impact

This issue breaks real-world integrations, especially with:

  • API gateways (Ocelot, YARP, NGINX) that rely on custom headers for routing
  • services requiring custom SOAP or security headers
  • authentication flows using custom header injections
  • helper AL libraries that prepare HttpClient headers before sending the request

In our case, missing headers caused Ocelot routing to fail with: UnableToFindDownstreamRouteError which made diagnosing the root cause extremely difficult.

5. Versions:

  • AL Language: 16.2.1869542
  • Visual Studio Code: 1.106.1
  • Business Central: BC 27.1
  • Operating System:
    • Windows
    • Linux
    • MacOS

Additional notes

  • This behavior is not documented in Microsoft Learn.
  • Likely cause: UseServerCertificateValidation(false) internally replaces the underlying HttpClient handler, discarding previously attached DefaultRequestHeaders.
  • A documentation update, warning, or preservation of header state would all be acceptable fixes.

Final Checklist

Please remember to do the following:

  • Search the issue repository to ensure you are reporting a new issue

  • Reproduce the issue after disabling all extensions except the AL Language extension

  • Simplify your code around the issue to better isolate the problem

Internal work item: AB#616817

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions