conductor-oss/conductor · critical · IllegalStateException
Each conductor.file-storage.conductor.signing.keys entry req
Error message
Each conductor.file-storage.conductor.signing.keys entry requires id and secret
What it means
Thrown by SigningProperties.validate() when signing is enabled and a key entry is null or has a blank id or blank secret. Each signing key must carry a non-blank id and a non-blank secret. Raised at startup as IllegalStateException, failing context initialization.
Source
Thrown at core/src/main/java/org/conductoross/conductor/core/storage/ConductorFileStorageProperties.java:116
@AssertTrue(message = "at least one signing key is required when signing is enabled")
public boolean isValid() {
return !enabled || (keys != null && !keys.isEmpty());
}
/** Throws a startup-friendly error for unusable key configuration. */
public void validate() {
if (!enabled) {
return;
}
if (keys == null || keys.isEmpty()) {
throw new IllegalStateException(
"conductor.file-storage.conductor.signing.keys is required when signing is enabled");
}
Set<String> ids = new HashSet<>();
for (Key key : keys) {
if (key == null || isBlank(key.getId()) || isBlank(key.getSecret())) {
throw new IllegalStateException(
"Each conductor.file-storage.conductor.signing.keys entry requires id and secret");
}
if (!ids.add(key.getId())) {
throw new IllegalStateException(
"conductor.file-storage.conductor.signing.keys contains duplicate id: "
+ key.getId());
}
}
}
private boolean isBlank(String value) {
return value == null || value.isBlank();
}
}
/** An ordered signing key. The first key signs new URLs; every key verifies existing URLs. */
public static class Key {
View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Ensure every keys entry has both a non-empty id and secret.
- Resolve the source env var/secret and confirm it is non-empty in the runtime environment.
- Use a secrets manager / devkey to inject the secret rather than hardcoding blanks.
Example fix
# before
signing:
enabled: true
keys:
- id: key-1
secret: # blank -> startup failure
# after
signing:
enabled: true
keys:
- id: key-1
secret: ${SIGNING_KEY_SECRET} Defensive patterns
Strategy: validation
Validate before calling
// Fail fast in a test:
for (Key k : props.getSigning().getKeys()) {
org.junit.jupiter.api.Assertions.assertFalse(
k.getId() == null || k.getId().isBlank() || k.getSecret() == null || k.getSecret().isBlank());
} Prevention
- Confirm signing secrets are non-empty in the runtime environment
- Resolve env vars before deploy and check they are set
- Do not leave secret placeholders blank in YAML
When it happens
Trigger: A keys entry with missing id, missing secret, or whitespace-only values, while conductor.file-storage.conductor.signing.enabled=true. For example a key with id set via an env var that resolves to empty.
Common situations: Secret supplied through an environment variable that is unset in the deployment; YAML key list with a placeholder that was never substituted; partial key object copied from docs with secret left blank.
Related errors
- conductor.file-storage.conductor.signing.keys is required wh
- conductor.file-storage.conductor.signing.keys contains dupli
- Configured file storage does not support content streaming
- workflowId is required
- File already uploaded: {}
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/0a03a4a6079c7bcf.
Report an issue: GitHub.