Intellij/Gradle sync fails behind Corporate proxy

The Fix: Put the ZScaler Root Cert into IJ

  1. Open Google Chrome
  2. Go to settings -> Security -> Manage Certificates
  3. Go to the "Trusted Root Certification Authorities" tab
  4. Scroll down to the item "ZScaler Root CA" - being a "Z" word it'll probably be near or at the bottom of the list
  5. Hit "Export..."
  6. Follow the steps of the Wizard to export your certificate as a .CER file & save it to somewhere on your machine
  7. Now open IntelliJ (IJ)
  8. Open settings (Ctrl+Alt+S)
  9. Search for "cert" to filter settings and go to "Server Certificates"
  10. Click on the little + icon
  11. Browse to the file you just saved and hit OK & OK again on settings

That should do it.

Note: the assumption is that you use Google Chrome the ZScaler root certificate is already stored in Chrome's trust store. If that's not the case for you, hopefully you will find another way to get the ZScaler Root cert. Worst case scenario: you could always ask your IT dept. who I'm sure are the ones managing ZScaler and should know how to get you the cert.

The More Detailed Discussion

This seems to be a general problem with IntelliJ (IJ), not just for a Gradle task but when IJ tries to connect to any HTTPS site, as pointed out by the comment of this user:

intellij uses a different secret store to your terminal.

Expanding on that comment, we note from the JetBrains documentation:

IntelliJ IDEA provides its own storage for trusted certificates.

Now, from that JetBrains doc and from this answer, one approach that would work is to simply accept all non-trusted certificates automatically. To understand why this is an OK approach, we recall that the whole problem was created in the first place by being behind ZScaler. Since you're behind ZScaler, you can trust that the ZScaler intermediate server that intercepts all your requests will block any untrustworthy sites for you, so you don't need to worry about it in IJ. Put another way, by the time ZScaler has forwarded those certs to IJ, you can already trust them.

However, the problem with that approach arises when your organisation has allowed you to disable ZScaler. In this case, if you disable ZScaler, then you are no longer protected by it. And when you do so, are you going to remember to revert your IJ settings? Maybe, but it would be an awful manual burden to do so. And more likely, you probably won't remember and then there's the possibility that your IJ can connect to untrustworthy sites. I don't know the full security details, so maybe there are some other measures taken to mitigate against such a vulnerability, but at the face of it this seems to me like a vulnerability. For example, an attacker could set up a fake update site for updating one of your IntelliJ plugins and install a malicious plugin instead, without you even knowing. And now you've effectively got a virus on your machine, because whenever you run IJ, the plugin runs too, and can probably do all sorts of bad stuff.

So a safer approach is to get to the root of the problem, literally: find the ZScaler root certificate and add that to the IJ trust store. Then IJ can trust that cert, and any downstream certs that ZScaler issues when intercepting your traffic.

Why the Root Certificate?

It's worth mentioning that the root certificate you add is not the same as the certificate that IJ warns you about when you suffer a problem. E.g. when I tried "check for updates" the cert that was causing the issue was issued to "*.google.com". I believe these are just the interceptor certs that ZScaler creates when it intercepts your traffic. The real cert for Google is used by ZScaler to communicate with Google. The "proxy" cert is the one that ZScaler generates to talk to your machine. Since ZScaler has to generate such a proxy cert for all imaginable sites, it's not enough to just add them to your trust store in IJ. Not only that, but these proxy certs appear to have pretty short shelf lives - the one I saw expired in two weeks. So you'd have to just keep re-adding them to the IJ trust store. And the IJ trust store would then just get cluttered up with all these temporary certs created by ZScaler. That's why you want to add the root cert. I believe it acts as the ultimate signing authority for any of those temporary proxy certs that are handed out. And the one I see doesn't expire for over 20 years. So I don't see myself having to fiddle with that IJ setting again for another while yet.

Notes

In essence, the fix given in this answer is effectively the same as this one, but I am expanding on how to actually get the ZScaler cert from Google Chrome settings, and I give some discussion about why we're doing what we're doing, and comparison to alternatives.


Mostly it can be related to certificate. To verify this, removing the option accepted certificates and checking "Accept non-trusted certificates automatically" may solves the issue. As @Colm Bhandal commented, it is not a solution , but a workaround solution.

enter image description here


The corporate issued certificate needs to be included in the truststore used by Gradle. Troubleshooting this can be difficult, especially if you have multiple versions of Java and the JRE installed. The first thing to determine is what JRE Gradle is using. There is an answer that points out the issue is resolved by using Gradle Wrapper. The Gradle Wrapper calls the project specific Java environment which is defined in gradle.properties. By default, it is set to distributionBase=GRADLE_USER_HOME. To get Gradle to build with untrusted certificates one can follow the instructions in the documentation:

The SSL certificate for the HTTP build cache backend may be untrusted since it is internally provisioned or a self-signed certificate.

In such a scenario, you can either configure the build JVM environment to trust the certificate, or set this property to true to disable verification of the server's identity.

Allowing communication with untrusted servers keeps data encrypted during transmission, but makes it easier for a man-in-the-middle to impersonate the intended server and capture data.

It is better to import the cert into the JVM used by Gradle which looks like what you were trying to do. If you want IntelliJ to know about the corporate certificate you can import those via the UI by Navigating to Settings > Tools > Server Certificates. Import the certificate file issued by your organization and retry the build.