conductor-oss/conductor · critical · IllegalStateException
conductor.file-storage.conductor.signing.keys contains dupli
Error message
conductor.file-storage.conductor.signing.keys contains duplicate id: {} What it means
Thrown by SigningProperties.validate() when two or more key entries share the same id. Signing keys are keyed by id (the first signs new URLs; all verify), so duplicate ids are ambiguous and rejected at startup with an IllegalStateException naming the offending id.
Source
Thrown at core/src/main/java/org/conductoross/conductor/core/storage/ConductorFileStorageProperties.java:120
}
/** 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 {
@NotBlank private String id;
@NotBlank private String secret;
public String getId() {View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Give each key entry a unique id (e.g. key-1, key-2).
- When rotating, keep the old key (same id is fine) only once and add a new key with a new id.
- Audit the resolved config for duplicates (print ids).
Example fix
# before - duplicate ids
signing:
enabled: true
keys:
- id: key-1
secret: ${OLD_SECRET}
- id: key-1
secret: ${NEW_SECRET}
# after - unique ids
signing:
enabled: true
keys:
- id: key-1
secret: ${OLD_SECRET}
- id: key-2
secret: ${NEW_SECRET} Defensive patterns
Strategy: validation
Validate before calling
Set<String> ids = props.getSigning().getKeys().stream().map(Key::getId).collect(Collectors.toSet()); boolean unique = ids.size() == props.getSigning().getKeys().size();
Prevention
- Give each signing key a unique id
- When rotating, add a new id rather than duplicating
- Audit merged config for duplicate key ids
When it happens
Trigger: Two entries under conductor.file-storage.conductor.signing.keys with the same id value while signing is enabled.
Common situations: Rotating keys by copy-pasting an entry and forgetting to change the id; merging config from multiple sources that both define key-1; templating that duplicates a key block.
Related errors
- conductor.file-storage.conductor.signing.keys is required wh
- Each conductor.file-storage.conductor.signing.keys entry req
- 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/8b3e62a9cc8513da.
Report an issue: GitHub.