Troubleshooting Server redirected too many times error
While configuring for a API integration where the application server accesses a https url from internet and authenticates for further operations like downloads, validations, etc. We encountered the “java.net.ProtocolException: Server redirected too many times (20)” error in application logs. most of the times its hard to know whether there is a issue with application code or with the proxy server configurations. So here we will discuss on how to troubleshoot the error and find the root cause to fix it at code level or at proxy server configuration level. In this article we will also discuss about different JVM options to enable proxy connection in JVM.
Discussion Topics Covered:
1. What is a proxy server and most common usage.
2. Enable proxy in java JVM
3. Troubleshooting Server redirected too many times error
3.a. Understanding the error.
3.b. Standalone programs to check connectivity.
3.c. Reproduce the errors, troubleshoot and report
3.d. Code level tips to honor access via proxy server
What is a proxy server and most common usage
A proxy server is an application that acts as an intermediary for requests from clients seeking resources from other servers. A client connects to the proxy server, requesting a file or web page and the proxy server evaluates the request before serving or blocking the same. Mostly in big organizations content filtering proxy is used to control web access. These proxies are usually configured to generate logs, either to give detailed information about the URLs accessed by specific users, or used to scan accessed contents via antivirus software to provide real time security against virus and other malwares before it enters the network.
Enable proxy in java JVM
To enable Java programs to access resources via proxy you need to add below details into your JVM arguments when the JVM starts. Here in below example we are using a authenticated https proxy server. You can check all configurations from Oracle site here
-Dhttps.proxyHost=usproxy01.techpaste.com -Dhttps.proxyPort=3128 -Dhttps.proxyUser=serviceproxy -Dhttps.proxyPassword=ddfs4hh#1 -Dhttp.nonProxyHosts="localhost|appserver1.techpaste.com"
Troubleshooting Server redirected too many times error
Usually this error is seen when access to a URL is redirecting in an infinite loop because of user session loss which is usually backed by a cookie. So in most cases developers need to create a CookieManager before using URLConnection. Here in this article we will be discussing how to identify if its a proxy settings issue or code issue.
In our scenario we use to get below error in our application logs so we created a standalone program to test the connection and make sure proxy settings are correct.
java.net.ProtocolException: Server redirected too many times (20) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at java.net.HttpURLConnection.getResponseCode(Unknown Source) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
Save below program as URLReaderWithOptions.java and use javac URLReaderWithOptions.java to compile the same to use.
Note: Update the Authenticator.setDefault(new ProxyAuthenticator(“serviceproxy”, “ddfs4hh#1”)); with your proxy username and password.
Example Java Program to test
import java.net.*; import java.io.*; /* * Using a URL to access resources on a secure site. * * You can optionally set the following command line options: * * -h <secure proxy server hostname> * -p <secure proxy server port> * -k <| separated list of protocol handlers> * -c <enabled cipher suites as a comma separated list> * */ public class URLReaderWithOptions { public static void main(String[] args) throws Exception { System.out.println("USAGE: java URLReaderWithOptions " + "[-h proxyhost] [-p proxyport] [-k protocolhandlerpkgs] " + "[-c ciphersarray]"); // initialize system properties char option = 'd'; int urlindex=args.length-1; for (int i = 0; i < args.length; i++) { System.out.println(option+": "+args[i]); switch(option) { case 'h': System.setProperty("https.proxyHost", args[i]); option = 'd'; break; case 'p': System.setProperty("https.proxyPort", args[i]); option = 'd'; break; case 'k': System.setProperty("java.protocol.handler.pkgs", args[i]); option = 'd'; break; case 'c': System.setProperty("https.cipherSuites", args[i]); option = 'd'; break; default: // get the next option if (args[i].startsWith("-")) { option = args[i].charAt(1); } } } Authenticator.setDefault(new ProxyAuthenticator("serviceproxymet", "dC9ssYzAAKuqY2Eg0m0h")); URL vURL = new URL(args[urlindex]); BufferedReader in = new BufferedReader( new InputStreamReader( vURL.openStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close(); } } class ProxyAuthenticator extends Authenticator { private String user, password; public ProxyAuthenticator(String user, String password) { this.user = user; this.password = password; } protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(user, password.toCharArray()); } }
Execute the program using below command:
java -Dhttps.proxyUser=<proxyuser> -Dhttps.proxyPassword=<proxypassword> URLReaderWithOptions -h <proxy_host_name> -p <proxy_port> <Target_URL>
Example:
java -Dhttps.proxyUser=serviceproxy -Dhttps.proxyPassword=dC9ssYzAAKuqY2Eg0m0h URLReaderWithOptions -h usproxy01.techpaste.com -p 3128 https://www.google.com
If you are able to access the url then the proxy server can be considered as working and the target url is white listed but incase you see errors like below then check with your proxy admin to allow the target url via proxy or white list the same.
Exception in thread "main" java.net.ProtocolException: Server redirected too many times (20) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source) at java.net.URL.openStream(Unknown Source) at URLReaderWithOptions.main(URLReaderWithOptions.java:58)
On Successful Access you will be able to see the html content of the target url:
Note: For any https urls access you need to add the ssl certificate of the target URL into your java keystore.
<JAVA_HOME>/bin/keytool -import -alias <server_name> -keystore <JAVA_HOME>/jre/lib/security/cacerts -file SSL_CA_Server.crt
In our case the proxy admin found that the target sites had not been listed for “decryption passthrough” so the proxy was presenting its own certificate and decrypting all the traffic to let the https urls accessible from the application server. You can easily see the access issues from the proxy server log files after running the test program with target URLs.
In case of any ©Copyright or missing credits issue please check CopyRights page for faster resolutions.
Log time problem solved. Thanks a lot for detailed post