Resource library

QA How-To

How to Fix REST Assured SSLHandshakeException

Fix REST Assured SSLHandshakeException with checks for CA trust, certificate chains, hostnames, mTLS, protocols, proxies, and Docker or CI configuration.

18 min read | 3,779 words

TL;DR

Inspect the nested handshake cause. For PKIX trust failures, verify the server chain and add the approved CA to a dedicated truststore used by the REST Assured request. For hostname, mTLS, protocol, or CI-only failures, fix that specific boundary and verify from the original runner with strict TLS checks.

Key Takeaways

  • Read the nested TLS cause before changing REST Assured configuration.
  • Use a dedicated truststore for an approved private CA and verify its fingerprint.
  • Repair incomplete chains and incorrect certificate hostnames at the server or route.
  • Supply a client keystore with a PrivateKeyEntry when the endpoint requires mTLS.
  • Compare TLS, proxy, JDK, and truststore behavior in the exact failing runner.
  • Rerun the original Java request with strict certificate validation enabled.

If you need to fix REST Assured SSLHandshakeException when an HTTPS API test starts, inspect the nested cause before changing the request. The exception appears during TLS setup, before REST Assured can assert an HTTP status or response body.

javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

That is one common form, not the only one. Save the full Caused by chain, the URL host, the Java runtime used by the test, and the failing runner name. Those four facts usually narrow the repair faster than rerunning an entire API suite.

TL;DR

For a private or corporate CA, obtain the approved CA certificate, verify its fingerprint through a trusted channel, import it into a dedicated PKCS12 truststore, and pass that store to the affected REST Assured request. For a public site, first check whether the server sends its intermediate certificates and whether the test runner uses the intended JDK. Use relaxedHTTPSValidation() only as a brief diagnostic in an isolated test, then remove it: that setting trusts invalid certificates and also relaxes hostname checks. The REST Assured SSL documentation describes both the shortcut and the scoped configuration.

openssl s_client -connect api.example.test:443 -servername api.example.test -showcerts -verify_return_error </dev/null
java -version
mvn -Dtest=ApiTlsTest -DargLine='-Djavax.net.debug=ssl,handshake,trustmanager' test

Replace api.example.test with the actual API hostname. The last command assumes the ApiTlsTest class below is in an existing Maven project with REST Assured and JUnit Jupiter installed. Match dependency versions to those already installed in that project; do not copy a guessed version pin.

What the Error Actually Means

SSLHandshakeException means the TLS peers could not complete a handshake. REST Assured normally delegates HTTPS work to its HTTP client and the Java security stack. A failure can occur while the client validates the server certificate, checks its hostname, selects a TLS protocol, or presents a client certificate for mutual TLS. An HTTP 401, 404, or 500 is different: the server completed TLS and returned an application response. If your assertion sees a status code, solve the HTTP failure instead of changing SSL settings.

Read the deepest useful line in the exception. PKIX path building failed points toward trust or chain construction. No subject alternative DNS name matching points toward a hostname mismatch. Received fatal alert: bad_certificate can indicate that the server rejected the client certificate. Received fatal alert: protocol_version indicates a protocol negotiation problem. These messages are evidence, not guaranteed diagnoses: a proxy can present a different certificate, and a load balancer can terminate TLS before your application sees a request.

JSSE tracing prints the offered and negotiated protocol, certificate processing, and trust-manager decisions. Oracle documents javax.net.debug=ssl,handshake,trustmanager in the JSSE reference guide. Keep the trace private because certificate details, endpoints, and other connection metadata may appear in CI artifacts. REST Assured request and response logging begins after much of this handshake work, so an empty response log does not mean the request never attempted a connection.

Root-Cause Decision Table

Symptom or nested message Likely root cause Fix and verification
PKIX path building failed for an internal endpoint Private CA absent from the test JVM's truststore Import the approved CA into a dedicated store; rerun the same test
OpenSSL shows a leaf but a missing intermediate Server sends an incomplete certificate chain Correct the server's full-chain configuration; inspect -showcerts again
No subject alternative DNS name matching URL host differs from certificate SAN Call the DNS name on the certificate and verify strict hostname checks
CertificateExpiredException or CertificateNotYetValidException Certificate validity or runner clock is wrong Renew or correct the clock; inspect validity and rerun
Received fatal alert: bad_certificate on an mTLS route Client key, certificate, or authorization is wrong Supply the correct client keystore; verify a private-key entry
Received fatal alert: protocol_version Client and server lack a permitted TLS version in common Align supported protocols; prove negotiation with OpenSSL and Java
Local test passes but CI fails behind a proxy Different CA, route, or interception certificate Probe from the CI worker and trust only its approved CA
Local test passes but container fails Wrong JDK, missing mounted store, or wrong store path Inspect inside the container, mount the store, rerun the test

Work from the observed row, not the first remedy you find online. The REST Assured tutorial covers normal request structure; TLS diagnosis starts one layer below those assertions.

1. Fix REST Assured SSLHandshakeException Caused by an Unknown CA

A private API may use a certificate issued by an enterprise CA that your browser trusts through the operating system, while the JVM running Maven does not. Another common error is importing the right certificate into a different JDK's cacerts. A dedicated project truststore makes the trust decision explicit and avoids modifying a shared JDK installation. Ask the certificate owner for the CA certificate and its SHA-256 fingerprint through a separate trusted channel. Do not import a certificate copied blindly from a failed connection.

Inspect the CA file before trusting it. Replace the example filename and alias with your team's approved values. keytool -importcert prompts for a new store password and, without -noprompt, asks you to confirm the certificate. Keep that password in your CI secret manager rather than a committed test file.

keytool -printcert -file certs/qa-root-ca.pem
keytool -importcert -alias qa-root-ca -file certs/qa-root-ca.pem -keystore certs/qa-trust.p12 -storetype PKCS12
keytool -list -v -alias qa-root-ca -keystore certs/qa-trust.p12 -storetype PKCS12

The list output must show a trustedCertEntry whose SHA-256 fingerprint matches the approved CA. Save this focused test as src/test/java/ApiTlsTest.java in a Maven project that already has REST Assured and JUnit Jupiter. The environment variables let the same test run against a real endpoint without committing its URL or store password. An accessible GET endpoint that returns 200 is needed for this smoke assertion; adapt the expected status to your API contract.

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.File;
import org.junit.jupiter.api.Test;

class ApiTlsTest {
  @Test
  void trustedApiResponds() {
    String url = System.getenv("API_HEALTH_URL");
    String password = System.getenv("TRUSTSTORE_PASSWORD");
    int status = given()
        .trustStore(new File("certs/qa-trust.p12"), password)
        .get(url)
        .statusCode();
    assertEquals(200, status);
  }
}
API_HEALTH_URL=https://api.example.test/health TRUSTSTORE_PASSWORD='<your-store-password>' mvn -Dtest=ApiTlsTest test

The success condition is a green test without PKIX path building failed. If the response is a different HTTP status, TLS may now be working; check the endpoint contract and authentication separately. Passing a File avoids ambiguity between a classpath resource and a filesystem path. The REST Assured request and response specification guide shows how to reuse scoped settings across tests.

2. Repair an Incomplete Server Certificate Chain

A leaf certificate may be valid and issued by a trusted CA, yet the TLS server might omit an intermediate certificate needed to reach that CA. Some browsers fetch or cache intermediates, so a browser success does not settle the Java result. The durable repair belongs on the server or TLS terminator: configure its certificate chain file to include the leaf and required intermediates in the order expected by that platform. The exact setting depends on your ingress, CDN, or web server; do not invent a generic flag and paste it into production.

Inspect what the endpoint actually sends using the hostname as Server Name Indication. OpenSSL's -showcerts prints the server-sent list; -verify_return_error stops on verification errors. If your workstation trusts an internal CA that OpenSSL does not, add its approved PEM file with -CAfile to make the verification comparison meaningful. This is a server-chain probe, not a substitute for the Java test.

openssl s_client -connect api.example.test:443 -servername api.example.test -showcerts -verify_return_error -CAfile certs/qa-root-ca.pem </dev/null

Read each subject and issuer, then compare the issuers with the next certificate in the sent chain. A missing intermediate can produce an issuer that never appears in the displayed list. After the server owner deploys its corrected chain, run the same command again and rerun ApiTlsTest from section 1. Both checks matter: OpenSSL validates with the CA file you supplied, while the Maven test exercises the JVM and REST Assured path. If the endpoint is behind several load balancer nodes, repeat the probe against each advertised address while retaining the correct SNI hostname. A fix on only one node leaves intermittent failures.

Avoid putting the current leaf certificate into a long-lived truststore as a workaround. The next certificate rotation would break tests again, and a copied leaf can hide the server's incomplete-chain defect from your test environment. Trust the approved issuing CA where policy allows, and fix chain delivery at the edge. For broader certificate-backed API coverage, see the API testing roadmap.

3. Correct the URL Hostname or Certificate SAN

A certificate can be trusted and still be wrong for the host in your REST Assured URL. Java verifies the DNS name or IP address in the certificate's Subject Alternative Name extension. Typical mistakes include calling a raw IP, using an internal service alias absent from the SAN, or following a redirect to a differently named endpoint. A truststore cannot make the wrong hostname correct. Do not use allowAllHostnames() to make a real test green: it removes the very check that detects impersonation or a wrong route.

Print the endpoint certificate and compare its SAN entries with the exact hostname in API_HEALTH_URL. For a public service, this command needs no CA file merely to inspect the certificate; perform full trust verification separately. keytool -printcert -sslserver is an inspection command, not proof that every HTTP client will validate the same route.

keytool -printcert -sslserver api.example.test:443 -v

If the approved certificate lists api.example.test, call that DNS name rather than a container IP. Keep the path and expected HTTP status the same in ApiTlsTest, then verify:

API_HEALTH_URL=https://api.example.test/health TRUSTSTORE_PASSWORD='<your-store-password>' mvn -Dtest=ApiTlsTest test

If you own the service and must support another hostname, request a new certificate with that DNS name in SAN and deploy it through the normal certificate process. For a temporary routing check, curl --resolve api.example.test:443:192.0.2.10 https://api.example.test/health connects to a chosen address while keeping the DNS name for HTTPS; replace the illustrative IP with the target node. That distinguishes DNS routing from certificate identity without disabling verification. The REST Assured logging filters guide helps capture request URLs when redirects or environment configuration make the actual destination unclear.

4. Replace an Expired Certificate or Correct the Runner Clock

CertificateExpiredException and CertificateNotYetValidException refer to the certificate's validity interval. The first often means a leaf or intermediate was not renewed; the second can occur when a certificate is deployed before its Not Before time or the worker's clock is behind. A certificate that looks fine on your laptop may fail in a worker with stale time or a different edge node. Preserve the certificate details and the runner's UTC time from the same moment.

date -u
keytool -printcert -sslserver api.example.test:443 -v
openssl s_client -connect api.example.test:443 -servername api.example.test -showcerts </dev/null

Inspect the validity dates for each relevant certificate, not just the leaf. If a certificate has expired, have the certificate owner renew and deploy the replacement with its correct chain. If the worker clock is wrong, repair its time synchronization through the runner or host configuration; changing local test code cannot make an invalid time source trustworthy. In a container, compare date -u inside the container with the host because containers normally use the host kernel clock.

After correction, rerun the same three commands and mvn -Dtest=ApiTlsTest test with the environment values from section 1. The expected observation is a current UTC time inside the certificate validity interval and a passing Java request. An HTTP error after that tells you to debug the API separately. Record certificate expiry monitoring for the endpoint, including intermediates where your platform exposes them. Testing only an already established keep-alive connection can miss a bad new handshake, so use a fresh process for verification.

5. Supply the Client Certificate for Mutual TLS

Some APIs require the caller to prove its identity with a client certificate. This is separate from trusting the server. The truststore contains certificates the client trusts; a client keystore must contain a private key and its matching certificate chain. Importing a public .cer into a truststore does not create a private key. The server may report bad_certificate or certificate_required; some gateways close the handshake with a less specific alert. Confirm the route's mTLS policy before changing REST Assured.

Ask your certificate administrator for a PKCS12 client keystore provisioned for the test identity. Inspect the alias type locally. The output must show PrivateKeyEntry; trustedCertEntry alone cannot authenticate the client. Use a separate server truststore because the two stores serve different purposes and may rotate on different schedules.

keytool -list -v -keystore certs/qa-client.p12 -storetype PKCS12
keytool -list -v -keystore certs/qa-trust.p12 -storetype PKCS12

For an mTLS smoke test, save the following as src/test/java/ApiMutualTlsTest.java. REST Assured's SSLConfig exposes keyStore, keystoreType, trustStore, and trustStoreType; both paths here refer to files in the Maven project. Keep the two passwords in secret variables.

import static io.restassured.RestAssured.given;
import static io.restassured.config.SSLConfig.sslConfig;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.File;
import org.junit.jupiter.api.Test;

class ApiMutualTlsTest {
  @Test
  void clientCertificateIsAccepted() {
    var ssl = sslConfig()
        .keyStore(new File("certs/qa-client.p12"), System.getenv("CLIENTSTORE_PASSWORD"))
        .keystoreType("PKCS12")
        .trustStore(new File("certs/qa-trust.p12"), System.getenv("TRUSTSTORE_PASSWORD"))
        .trustStoreType("PKCS12");
    int status = given()
        .config(io.restassured.RestAssured.config().sslConfig(ssl))
        .get(System.getenv("API_HEALTH_URL"))
        .statusCode();
    assertEquals(200, status);
  }
}
API_HEALTH_URL=https://api.example.test/health CLIENTSTORE_PASSWORD='<your-client-password>' TRUSTSTORE_PASSWORD='<your-trust-password>' mvn -Dtest=ApiMutualTlsTest test

A green result proves that this endpoint accepted the presented identity and completed the API call. If the handshake succeeds but the server returns 403, inspect the certificate subject, issuing CA, and gateway authorization mapping rather than adding more trust anchors. For bearer-token authentication after TLS, see REST Assured OAuth2 authentication; an OAuth token does not replace an mTLS private key.

6. Align TLS Protocols and Cipher Policy

Received fatal alert: protocol_version means a peer rejected the offered protocol version. A related handshake_failure can arise when no permitted cipher suite or signature algorithm overlaps, although that alert is less specific. Inspect what the client and server support before forcing a protocol. Modern JDKs and gateways may disable older protocols by policy, and weakening either side to accept an obsolete protocol is a security regression. REST Assured's relaxedHTTPSValidation("TLS") names an SSLContext algorithm while disabling certificate validation; it is not a safe protocol-negotiation fix.

Check the server with both explicit OpenSSL modes from the same network location as the test runner. A successful command reports a negotiated protocol and cipher; an unsuccessful command shows an alert or connection failure. These tests do not prove the Java client supports exactly the same set, so follow them with JSSE tracing.

openssl s_client -connect api.example.test:443 -servername api.example.test -tls1_2 </dev/null
openssl s_client -connect api.example.test:443 -servername api.example.test -tls1_3 </dev/null
java -version

Run the Java test with trace output in a controlled job. For Maven Surefire, argLine passes a JVM argument to a forked test process. If your project already sets argLine for another agent, preserve that configuration when adding the debug property. The Maven Surefire system-property guide explains the distinction.

API_HEALTH_URL=https://api.example.test/health TRUSTSTORE_PASSWORD='<your-store-password>' mvn -Dtest=ApiTlsTest -DargLine='-Djavax.net.debug=ssl,handshake' test

Compare the ClientHello offer and the server's response. If the server only accepts an older protocol disallowed by your supported JDK, have the service owner enable a current common protocol and certificate setup. If the Java runtime is unexpectedly old, switch the build image to an organization-approved JDK that meets the service's TLS policy. Verify by rerunning the explicit OpenSSL probe and the original Java test. Avoid copying arbitrary jdk.tls.disabledAlgorithms changes into CI: that would alter the policy for every connection in that JVM.

7. Fix REST Assured SSLHandshakeException Behind a Proxy

An HTTPS-intercepting proxy may issue a substitute certificate signed by a corporate CA. Your workstation can trust it through managed system settings while a separate CI JVM does not. A proxy can also fail to tunnel the request or send the test to a different hostname. Compare the certificate issuer on the runner with the one on a known direct route. Ask your network team which CA and proxy endpoint are approved; do not accept a certificate solely because it appeared in a failing trace.

Check the proxy environment and probe with the same routing policy the Java test uses. curl -v reports connection and certificate information, but curl often uses a different CA store from Java. If REST Assured is configured with an explicit proxy, keep that setting in the request specification so the probe and the test traverse the same boundary.

printenv HTTPS_PROXY HTTP_PROXY NO_PROXY
curl -vI https://api.example.test/health

Here is a scoped REST Assured proxy variant. It uses the same truststore as section 1 and names an approved proxy host and port supplied by the job. Save it as src/test/java/ApiProxyTlsTest.java.

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.File;
import org.junit.jupiter.api.Test;

class ApiProxyTlsTest {
  @Test
  void proxiedApiResponds() {
    int status = given()
        .proxy(System.getenv("API_PROXY_HOST"), Integer.parseInt(System.getenv("API_PROXY_PORT")))
        .trustStore(new File("certs/qa-trust.p12"), System.getenv("TRUSTSTORE_PASSWORD"))
        .get(System.getenv("API_HEALTH_URL"))
        .statusCode();
    assertEquals(200, status);
  }
}
API_PROXY_HOST=proxy.example.test API_PROXY_PORT=8080 API_HEALTH_URL=https://api.example.test/health TRUSTSTORE_PASSWORD='<your-store-password>' mvn -Dtest=ApiProxyTlsTest test

If interception is intentional, add the approved proxy CA to a dedicated truststore and verify its fingerprint before using it. If interception is forbidden for this API, correct proxy bypass routing instead. A 407 means proxy authentication failed after reaching the proxy, so treat it as an HTTP proxy configuration issue rather than a server certificate repair. Compare the successful test's certificate issuer and route with the failing run to confirm you fixed the intended boundary.

8. Keep CI and Docker on the Same Trust Configuration

A green laptop run and red pipeline often involve two different Java homes. The Docker image may have a different cacerts set, the PKCS12 file may never be copied or mounted, or a relative certs/qa-trust.p12 path may resolve from an unexpected working directory. Check these facts inside the exact test container. Do not rely on a host-side keytool -list result to prove that the container can read the file.

In the CI job, print the Java location and inspect the mounted truststore alias before Maven starts. Avoid printing the store password. The following commands assume the container's working directory is the Maven project and the store was mounted at certs/qa-trust.p12.

java -version
command -v java
pwd
keytool -list -alias qa-root-ca -keystore certs/qa-trust.p12 -storetype PKCS12

For an illustrative local Docker check, use a Maven image whose JDK and Maven versions match your project's approved versions. Replace <your-maven-and-jdk-tag> with that exact tag. Mount the project read-only if the build writes only to a separate work area, or use your normal CI volume layout. The example below mounts the project read-write so Maven can create target/; it passes the password from the host environment without embedding it in an image layer.

docker run --rm -v "$PWD:/workspace" -w /workspace -e API_HEALTH_URL -e TRUSTSTORE_PASSWORD 'maven:<your-maven-and-jdk-tag>' mvn -Dtest=ApiTlsTest test

Set API_HEALTH_URL and TRUSTSTORE_PASSWORD in the invoking shell or CI secret environment first. Use your organization's approved image tag and match its JDK to the one supported by the project. The verification is a green ApiTlsTest from inside the container and an alias lookup from inside that same image. If the command cannot reach the API at all, check DNS and network routing before changing certificates. If the store path is missing, mount the approved file or use an absolute path passed through a test property; do not silently fall back to relaxedHTTPSValidation().

How to Verify the Fix

Verify the failed handshake on the same URL, runner, and route that originally failed. Run the smallest relevant class: ApiTlsTest for server trust, ApiMutualTlsTest for client authentication, or ApiProxyTlsTest for the proxy route. Then rerun the original test that exposed the error. Compare the nested exception and JSSE trace from before and after. A successful TLS connection followed by an HTTP 401 is progress in transport but not proof that the full API scenario is correct.

For an intermittent failure, test each load balancer node or runner pool separately. Record the server certificate issuer, serial number, SAN, validity dates, Java vendor and version, container image tag, and truststore alias. These are the details most likely to differ between a passing and failing machine. If a corporate proxy is involved, record whether the request used the proxy and which issuer it presented. Remove any temporary debug trace from routine CI once the repair is confirmed, or restrict its artifact retention and access.

Use the API testing scenario questions to practice explaining why a transport failure must be solved before response assertions. For a framework-wide solution, apply a carefully scoped request specification, then cover it with one smoke test rather than changing global REST Assured state in every class.

Prevent It From Coming Back

Own the certificate lifecycle. Monitor endpoint expiry, provision the complete server chain, and update dedicated truststores when an approved CA rotates. Store client keystores and their passwords through the CI secret system, with a documented renewal owner. Keep test and production trust boundaries separate so a QA-only CA does not quietly become trusted everywhere. A truststore file in a repository can be acceptable only when its contents are public CA certificates and your team's review policy allows it; a client keystore containing a private key needs protected distribution.

Pin the build to an approved JDK and container image, and record their versions in CI output. Add a preflight command that checks the truststore alias and a targeted HTTPS smoke test before a large API suite. If a gateway, proxy, or DNS route changes, run the preflight from each runner pool. The REST Assured framework build guide can help place this check in a reusable test setup.

Interview Questions and Answers

Q: What is the first clue in an SSLHandshakeException? Read the nested cause and identify the handshake stage. PKIX path building failed suggests trust-path construction, while bad_certificate on an mTLS endpoint points toward client identity.

Q: Why can a browser connect while a REST Assured test fails? The browser and JVM may use different trust stores, proxy routes, or cached intermediate certificates. Compare certificates and routes from the exact runner.

Q: What does a truststore hold? It holds certificates the client accepts as trust anchors or trusted entries. It does not normally supply the private key needed for mutual TLS.

Q: Why is a server full-chain fix preferable to importing its leaf certificate? The server should supply intermediates needed to build a path. Importing a leaf couples tests to one certificate rotation and can conceal the deployment defect.

Q: How do you debug a hostname mismatch? Compare the exact request host with certificate SAN entries and check redirects. Use the intended DNS name or issue a certificate for the required name.

Q: What does javax.net.debug add? It shows handshake messages and trust-manager decisions from the Java process. Run it only on a focused test and protect its output.

Q: How do you distinguish mTLS failure from server trust failure? Inspect which peer rejects which certificate and whether the client keystore contains a PrivateKeyEntry. A server trust failure occurs while the client validates the server; mTLS adds server validation of the client.

Common Mistakes

  • Calling relaxedHTTPSValidation() the permanent fix. It bypasses certificate trust and hostname validation, so it erases the property the test should verify.
  • Importing a certificate into the laptop JDK while Surefire runs under another JDK or Docker image. Check java -version inside the failing environment.
  • Treating curl success as proof of Java trust. Curl and JSSE may use different CA sources, proxy settings, and TLS implementations.
  • Putting a client certificate without its private key in the mTLS keystore. Check for PrivateKeyEntry with keytool -list -v.
  • Importing an unverified certificate downloaded from the failing endpoint. Obtain the CA and fingerprint through an approved channel first.
  • Changing global TLS policy to solve one service. Scope the truststore to the request or test runner that needs it.
  • Fixing one load balancer node and declaring victory after a single pass. Probe all nodes and the original CI route.

Conclusion

To fix REST Assured SSLHandshakeException, use the nested TLS message to select a specific check, repair the certificate, hostname, client identity, protocol, or runner configuration at its source, and rerun the same Java test. Preserve strict validation in the final test. A green request from the original runner is the evidence that the handshake repair actually reached your API.

Interview Questions and Answers

How would you triage a REST Assured SSLHandshakeException in CI?

I would capture the deepest cause and the JSSE handshake trace from one focused test. Then I would compare the runner's Java version, route, certificate chain, and truststore alias with the passing environment. I would change only the failing boundary and rerun the original request on that runner.

What does PKIX path building failed tell you?

The client could not construct a trusted certificate path for the peer it saw. That may mean an unknown private CA, an incomplete server chain, or a proxy presenting a different issuer. I would inspect the presented chain before importing anything.

How do you distinguish a server certificate problem from an mTLS client certificate problem?

I locate the failing validation step in the handshake trace and inspect whether the route requests a client certificate. Server validation needs the correct trust anchors and hostname. Client authentication needs a keystore with a private key and a certificate the server authorizes.

Why should an API test avoid relaxedHTTPSValidation in its final configuration?

It makes invalid server certificates acceptable and also relaxes hostname checking. The test can pass against a wrong endpoint or an intercepted connection. I would replace it with approved trust material and strict verification.

What would you check when browser HTTPS works but REST Assured fails?

I would compare trust sources, proxy routing, and the certificate chain visible to each client. Browsers may have OS-managed roots or cached intermediates that the JVM does not. The decisive verification is a Java request on the failing runner.

How do you validate a certificate-chain repair?

I would query the endpoint with SNI and inspect the server-sent certificates after deployment. Then I would rerun the focused REST Assured test with strict validation. I would repeat across load balancer nodes if the failure was intermittent.

What does a PrivateKeyEntry indicate in a client keystore?

It indicates that the keystore holds private-key material with its certificate chain, which is required to present a client identity for mTLS. A trustedCertEntry alone contains a trusted certificate, not an identity the client can prove it owns. I would also verify that the server authorizes that identity.

Frequently Asked Questions

How do I fix PKIX path building failed in REST Assured?

First confirm whether the server sends its intermediate certificates. If it does and the issuer is an approved private CA, import that CA into a dedicated truststore after verifying its fingerprint, then pass the store to the affected REST Assured request and rerun it.

Should I use relaxedHTTPSValidation to solve SSLHandshakeException?

Use it only as a short-lived diagnostic in an isolated environment. It disables certificate validation and relaxes hostname checks, so the lasting repair is to correct trust, chain delivery, hostname, or client identity.

What is the difference between a Java truststore and a client keystore?

A truststore identifies certificates the client trusts when validating a server. A client keystore for mTLS contains a private key and matching certificate chain that the client presents to the server. Check for a PrivateKeyEntry when diagnosing mTLS.

Why does REST Assured fail in Docker when it works locally?

The container can use a different JDK truststore, lack the mounted PKCS12 file, resolve a different path, or traverse a different network route. Inspect Java, the store alias, and the endpoint from inside the same container that runs Maven.

Can a missing intermediate certificate cause SSLHandshakeException?

Yes. Java may be unable to build a path from the server leaf to a trusted CA if the TLS terminator omits an intermediate. Inspect the server-sent chain with OpenSSL, repair its full-chain deployment, and rerun the Java request.

Does curl success prove that REST Assured will trust the server?

No. Curl and Java can use different CA sources and proxy routes. Treat curl as a network and certificate probe, then verify with the original REST Assured test under the failing JDK.

How do I debug SSLHandshakeException caused by a hostname mismatch?

Print the certificate SAN entries and compare them with the exact HTTPS URL host, including redirects. Call the certified DNS name or deploy a certificate containing the required name; keep strict hostname verification enabled.

Related Guides