Trying to fetch non-existing certificate results in 500 error being thrown
Describe the bug
If you try to fetch a certificate using the API (/api/v1/pki/certificates/{serialNumber}, /api/v1/pki/certificates/{serialNumber}/body, /api/v1/pki/certificates/{serialNumber}/bundle etc) the backend will return 500 Internal Server Error.
This is happening because it's trying to grab the projectId from cert (which is null) and pass that into the PermissionService to see if we're allowed to view it (I'm assuming given the name of the service).
Link to broken code: (Error on L286) https://github.com/Infisical/infisical/blob/b54e3d1e4244b0cc05cba1e4bf5b663ad16fa553/backend/src/services/certificate/certificate-service.ts#L281-L290
To Reproduce
Steps to reproduce the behavior:
GET /api/v1/pki/certificate/non-existant-serial
GET /api/v1/pki/certificate/non-existant-serial/body
GET /api/v1/pki/certificate/non-existant-serial/bundle
GET /api/v1/pki/certificate/non-existant-serial/private-key
Expected behavior
I would expect it to throw 404 Not Found EDIT: As now there would be no way to differentiate between a non-existant certificate, and postgres having gone down.
Screenshots
infisical-backend | {"level":30,"time":1759990775046,"pid":1,"hostname":"9a14ab467071","reqId":"req-Mid57PMhw6JLWU","severity":"INFO","req":{"method":"GET","url":"/api/v1/pki/certificates/79ae4908edbadaaf66a0ea6181f781b09370be4f/certificate","hostname":"10.0.0.16:8080","remoteAddress":"172.19.0.1","remotePort":34960},"msg":"incoming request"}
infisical-backend | {"level":30,"time":1759990775055,"pid":1,"hostname":"9a14ab467071","reqId":"req-Mid57PMhw6JLWU","orgId":"<REDACTED>","severity":"INFO","msg":"injectPermission: Injecting permissions for [permissionsForIdentity=<REDACTED>] [type=identity]"}
infisical-backend | {"level":30,"time":1759990775055,"pid":1,"hostname":"9a14ab467071","reqId":"req-Mid57PMhw6JLWU","orgId":"<REDACTED>","severity":"INFO","msg":"getPlan: attempting to fetch plan for [orgId=<REDACTED>] [projectId=undefined]"}
infisical-backend | {"level":30,"time":1759990775055,"pid":1,"hostname":"9a14ab467071","reqId":"req-Mid57PMhw6JLWU","orgId":"<REDACTED>","severity":"INFO","msg":"getPlan: Process done for [orgId=<REDACTED>] [projectId=undefined]"}
infisical-backend | {"level":50,"time":1759990775056,"pid":1,"hostname":"9a14ab467071","reqId":"req-Mid57PMhw6JLWU","severity":"ERROR","err":{"type":"TypeError","message":"Cannot read properties of undefined (reading 'projectId')","stack":"TypeError: Cannot read properties of undefined (reading 'projectId')\n at Object.getCertBody (/backend/src/services/certificate/certificate-service.ts:245:23)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async Object.handler (/backend/src/server/routes/v1/certificate-router.ts:591:69)"},"msg":"Cannot read properties of undefined (reading 'projectId')"}
infisical-backend | {"level":30,"time":1759990775057,"pid":1,"hostname":"9a14ab467071","reqId":"req-Mid57PMhw6JLWU","severity":"INFO","res":{"statusCode":500},"responseTime":10.363909006118774,"msg":"request completed"}
(I've redacted orgId out of habbit)
Platform you are having the issue on:
- Self-Hosted.
- Docker running
latest - Docker running
v0.146.0(dev-env mirrors production) - Production linux-package
v0.146.0
- Docker running
Additional Context
The more "writing" endpoints have similar issues as well.
Example being POST /api/v1/pki/certificates/{serialNumber}/revoke will throw a 500 Error on non-existant certificates because of L194: https://github.com/Infisical/infisical/blob/main/backend/src/services/certificate/certificate-service.ts#L192C1-L198C6
would like to work this - someone plz assign it to me
:
🛠️ I’d like to take this issue
Hi @bkcsoft @maidul98 👋 — I’d like to work on fixing this issue.
Summary of the bug:
When fetching or revoking a certificate using its serial number, if the certificate doesn’t exist, the backend still tries to access cert.projectId. Since cert is undefined, it throws a TypeError and returns a 500 Internal Server Error instead of a proper 404 Not Found.
Proposed fix:
Add an early check after certificateDAL.findOne({ serialNumber }).
If no certificate is found → return 404 Not Found.
Run permission checks only after confirming the certificate exists.
Apply this pattern consistently across the related endpoints (/body, /bundle, /revoke, etc.).
This will make the API responses more accurate and prevent false 500s.
I’ll open a PR shortly with this fix. 🚀