We run Dependency-Track for vulnerability analysis across our projects. One day, the OSS Index integration stopped working. No API calls, no analysis results, just this in the logs:
An error occurred decrypting the OSS Index API Token; Skipping [projectName=Balansen - BatchConsole, vulnAnalysisLevel=PERIODIC_ANALYSIS, projectUuid=14ba5633-58c2-45fe-9f04-e4ab0b28375e, projectVersion=DEV]
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
BadPaddingException is Java's polite way of saying: "I tried to decrypt this with a key, and it's the wrong key." The API token itself was fine. The key used to decrypt it wasn't.
The wrong assumption
Our first instinct was to re-enter the OSS Index credentials in the UI and assume a fat-fingered token was the culprit. That didn't help. The error came back on the next analysis run, right after we restarted the container for an unrelated update.
That restart was the actual clue.
The real cause
Dependency-Track encrypts sensitive values — API keys, tokens, LDAP passwords — using a secret key it generates on first startup. That key is normally stored on disk, under /data/.dependency-track/keys/secret.key inside the container.
We hadn't mounted a persistent volume for that path. So every time the container restarted or a new one spun up, Dependency-Track generated a brand new encryption key. Any secret that had been encrypted with the previous key became permanently undecryptable, since the key needed to unlock it no longer existed anywhere.
The OSS Index API token wasn't corrupted. It was encrypted with a key that had already been thrown away.
The fix
Mount a persistent volume for the Dependency-Track data directory so the encryption key (and other state) survives container restarts and redeployments:
services:
dtrack-apiserver:
image: dependencytrack/apiserver:latest
volumes:
- dependency-track-data:/data
ports:
- "8081:8080"
volumes:
dependency-track-data:
If you're on Kubernetes, the equivalent is a PersistentVolumeClaim mounted at /data in the API server's pod spec. The important part isn't the platform, it's making sure /data/.dependency-track/keys/secret.key is the same file across every restart.
Cleaning up after the fact
Mounting the volume prevents future key rotation. It doesn't fix secrets that were already encrypted with a key that's now gone. For those, there's no way to recover the original value; you have to re-enter them:
- OSS Index API token: Administration → Analyzers → OSS Index
- Any other integration credentials (Snyk, Defect Dojo, LDAP bind password, etc.) affected the same way
After re-entering, trigger a manual analysis on an affected project to confirm the BadPaddingException is gone.
Takeaway
If you see BadPaddingException on decryption in Dependency-Track, don't chase the secret value first. Check whether the container's data directory is actually persistent. An ephemeral filesystem for /data means an ephemeral encryption key, and an ephemeral encryption key means every secret you configure has a shelf life of "until the next restart."
