I am using Gatling 3.13.1 with Maven and need help configuring a gRPC request with a self-signed certificate.
Setup
I have generated the following files and used them to start my gRPC server:
privateKey.pem
certificate.pem
To verify that the server works correctly, I wrote a Java main method that successfully makes a request to the server (code is not provided now but I can provide it if needed it). However, when trying to perform the same request using Gatling, I run into an issue.
Gatling Configuration
I have a configuration file where I define the necessary properties:
grpcHost=localhost
grpcPort=9091
certificate.path=path/to/certificate.pem
I then read these properties in my Gatling setup:
String certificatePath = configProperties.getProperty(“certificate.path”);
return grpc.forAddress(configProperties.getGrpcHost(), configProperties.getGrpcPort())
.useCustomCertificateTrustManager(certificatePath);
This method returns a GrpcProtocolBuilder
. I have also tried .useStandardTrustManager()
, but the issue remains the same.
Error Message
When executing the test in Gatling, I receive the following error:
gRPC stream end:
status:
code: UNAVAILABLE
description: io exception
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0]
cause: javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
I suspect I am missing something in my Gatling configuration. Could you help me identify the issue and guide me on how to correctly pass the self-signed certificate to Gatling for gRPC requests?
I would really appreciate any insights!
I’ve triple check this part of the code and I fail to see how there could be an issue there.
Possible issues (some might sound stupid, but better safe than sorry as we’ve encountered them):
- you’ve made a mistake while copying the correct certificate into your project
- the certificate is not in X509 format
certificate.path
must be a classpath path, eg the relative path from src/test/resources
, not a filesystem path
- the code version you’re executing is not the one you have locally (eg forgot to push on a git repo or to re-upload a package)
- you’ve made a mistake while copying the correct certificate into your project
I verified that I copied the correct certificate from my gRPC server.
- the certificate is not in X509 format
I double-checked, and the certificate is in X.509 format.
certificate.path
must be a classpath path, eg the relative path from src/test/resources
, not a filesystem path
Initially, I was using an absolute path:
C:/Users/myuser/path/to/certificate.pem.
I corrected it to a classpath path:
src/main/resources/certificate.pem and I am able to see information about certificate (as before).
My Java code reads the certificate as follows:
String certificatePath = configProperties.getProperty(“certificate.path”);
CertificateFactory certificateFactory = CertificateFactory.getInstance(“X.509”);
FileInputStream certInputStream = new FileInputStream(certificatePath);
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(certInputStream);
log.info("Certificate's information:");
log.info("Issuer: {}", certificate.getIssuerDN());
log.info("Subject: {}", certificate.getSubjectDN());
log.info("Serial Number: {}", certificate.getSerialNumber());
log.info("Not Before: {}", certificate.getNotBefore());
log.info("Not After: {}", certificate.getNotAfter());
log.info("Signature Algorithm: {}", certificate.getSigAlgName());
return grpc.forAddress(configProperties.getGrpcHost(),configProperties.getGrpcPort())
.useCustomCertificateTrustManager(certificatePath);
Output of above logs
Certificate’s information:
Issuer: CN=localhost
Subject: CN=localhost
Serial Number: 721581440726280250068496780889873755888237740866
Not Before: Mon Mar 31 22:06:18 EEST 2025
Not After: Tue Mar 31 22:06:18 EEST 2026
Signature Algorithm: SHA256withRSA
- the code version you’re executing is not the one you have locally (eg forgot to push on a git repo or to re-upload a package)
I am running this locally, so there is no issue related to uncommitted or outdated code from a Git repository.
Behavior Without SSL when using
grpc.forAddress(configProperties.getGrpcHost(), configProperties.getGrpcPort())
.usePlaintext();
or
grpc.forAddress(configProperties.getGrpcHost(), configProperties.getGrpcPort())
.useInsecureTrustManager();
the gRPC service is accessible, meaning the connection works without certificate validation.
I do agree with you that most probably I miss something small and could be something stupid.
Do you have any other idea what could be wrong?
Are there any additional logs I could enable to get more insight into the problem?
Would it help if I provided details on how I created my self-signed certificate?
Any ideas or suggestions would be greatly appreciated!
Update: I run my simulation with command ‘mvn gatling:test’
I corrected it to a classpath path:
src/main/resources/certificate.pem and I am able to see information about certificate (as before).
My Java code reads the certificate as follows:
String certificatePath = configProperties.getProperty(“certificate.path”);
This is wrong.
src/main/resources/certificate.pem
is a relative filesystem path, not a classpath path.
You should actually be passing certificate.pem
(with certificate.pem
being located in src/main/resources
).
You should actually be passing certificate.pem
(with certificate.pem
being located in src/main/resources
).
Issue is fixed!
certificate located into: src/main/resources/certificate.pem
So I pass (as you said) certificate.pem and it is working with no problem.
many thanks!
with certificate.pem
being located in src/main/resources
Is it strictly required to place certificate.pem
inside src/main/resources
or src/test/resources
, or are there alternative locations where it can be stored?
So I pass (as you said) certificate.pem and it is working with no problem.
Great news. Still, I would have expected us to detect that the resources is missing and crash upfront. I’ll investigate.
Is it strictly required to place certificate.pem
inside src/main/resources
or src/test/resources
, or are there alternative locations where it can be stored?
Strictly required.
Note that there’s nothing sensitive in this file.
Great news. Still, I would have expected us to detect that the resources is missing and crash upfront. I’ll investigate.
That’s why I asked you if I can open some more logs to see where exactly it is failing.
Strictly required.
Note that there’s nothing sensitive in this file.
Clear.
Strictly required.
Note: I’m going to change this to align with standard Gatling behavior regarding certificates and allow absolute paths too.
That’s why I asked you if I can open some more logs to see where exactly it is failing.
Yeah, I see that our gRPC plugin doesn’t reuse core Gatling’s Ssl
helper. Fixing.
Note: I’m going to change this to align with standard Gatling behavior regarding certificates and allow absolute paths too.
Do you have any ETA for this? 
Not sure, maybe next month.
1 Like