{"record":{"id":"8b3e62a9cc8513da","repo":"conductor-oss/conductor","slug":"conductor-file-storage-conductor-signing-keys-cont","errorCode":null,"errorMessage":"conductor.file-storage.conductor.signing.keys contains duplicate id: {}","messagePattern":"conductor\\.file-storage\\.conductor\\.signing\\.keys contains duplicate id: (.+?)","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"core/src/main/java/org/conductoross/conductor/core/storage/ConductorFileStorageProperties.java","lineNumber":120,"sourceCode":"        }\n\n        /** Throws a startup-friendly error for unusable key configuration. */\n        public void validate() {\n            if (!enabled) {\n                return;\n            }\n            if (keys == null || keys.isEmpty()) {\n                throw new IllegalStateException(\n                        \"conductor.file-storage.conductor.signing.keys is required when signing is enabled\");\n            }\n            Set<String> ids = new HashSet<>();\n            for (Key key : keys) {\n                if (key == null || isBlank(key.getId()) || isBlank(key.getSecret())) {\n                    throw new IllegalStateException(\n                            \"Each conductor.file-storage.conductor.signing.keys entry requires id and secret\");\n                }\n                if (!ids.add(key.getId())) {\n                    throw new IllegalStateException(\n                            \"conductor.file-storage.conductor.signing.keys contains duplicate id: \"\n                                    + key.getId());\n                }\n            }\n        }\n\n        private boolean isBlank(String value) {\n            return value == null || value.isBlank();\n        }\n    }\n\n    /** An ordered signing key. The first key signs new URLs; every key verifies existing URLs. */\n    public static class Key {\n\n        @NotBlank private String id;\n        @NotBlank private String secret;\n\n        public String getId() {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/core/src/main/java/org/conductoross/conductor/core/storage/ConductorFileStorageProperties.java#L102-L138","documentation":"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.","triggerScenarios":"Two entries under conductor.file-storage.conductor.signing.keys with the same id value while signing is enabled.","commonSituations":"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.","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)."],"exampleFix":"# before - duplicate ids\nsigning:\n  enabled: true\n  keys:\n    - id: key-1\n      secret: ${OLD_SECRET}\n    - id: key-1\n      secret: ${NEW_SECRET}\n\n# after - unique ids\nsigning:\n  enabled: true\n  keys:\n    - id: key-1\n      secret: ${OLD_SECRET}\n    - id: key-2\n      secret: ${NEW_SECRET}","handlingStrategy":"validation","validationCode":"Set<String> ids = props.getSigning().getKeys().stream().map(Key::getId).collect(Collectors.toSet());\nboolean unique = ids.size() == props.getSigning().getKeys().size();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give each signing key a unique id","When rotating, add a new id rather than duplicating","Audit merged config for duplicate key ids"],"tags":["config","signing","startup","file-storage","conductor","java"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}