Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8340182

Java HttpClient does not follow default retry limit of 3 retries

XMLWordPrintable

    • x86_64
    • linux

      ADDITIONAL SYSTEM INFORMATION :
      Same on both Linux based and Windows, Java JDK or JRE version 21.0.4.

      A DESCRIPTION OF THE PROBLEM :
      The Java HttpClient does not respect the default retry limit of 3 retries in case of invalid credentials supplied with a basic auth scheme.
      Instead of 3 retries it goes for 4 times.
      This is true even if custom retry limit is used e.g. 1 or 2 (via property "jdk.httpclient.auth.retrylimit"), it goes for 2 or 3 retries respective.
      The number of retries is always one larger than the actual limit.


      Seems the problem lies in this condition in the source code for the client: https://github.com/openjdk/jdk/blob/master/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java#L323
      The condition in the if statement "au.retries > retry_limit" should maybe be "au.retries >= retry_limit"?

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Execute the following code (that on purpose uses invalid credentials) and observe the printouts and the error message printed from the exception stack:

      public static void main(String[] args)
      {
      int i[] = { 1 };
      try
      {

      HttpClient client = HttpClient.newBuilder()
      .authenticator(new Authenticator(){
      @Override
      protected PasswordAuthentication getPasswordAuthentication()
      {
      System.out.println("Try no. " + i[0]++);
      return new PasswordAuthentication("username", "password".toCharArray());
      }
      })
      .build();

      HttpRequest request = HttpRequest.newBuilder()
      .GET()
      .uri(new URI("https://postman-echo.com/basic-auth"))
      .build();

      HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
      }
      catch (Exception e)
      {
      System.out.println("Happens at try no. " + --i[0]);
      e.printStackTrace();
      }
      }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The expected scenario is that an exception will happen at try no. 3 as that is the default limit for retries according to https://github.com/openjdk/jdk/blob/master/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java#L55
      Other scenario that might be expected is that a try no. 4 will not happen i.e. the client will not try to get the credentials for the 4th time if the limit is 3.
      ACTUAL -
      The retry logic does not stop at 3 and it actually goes for another round and executes 4 times thus retrieving and executing the request 4 times instead of 3 times according to the limit and here is also the error from the exception than states that the limit is 3 but 4 times were tried.

      CUSTOMER SUBMITTED WORKAROUND :
      No workaround as of now.
      It seems the condition check in is wrong?
      I should be ">=" instead of ">"?

      FREQUENCY : always


            michaelm Michael McMahon
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: