{"record":{"id":"98b205dc3a3a1189","repo":"Netflix/Hystrix","slug":"another-strategy-was-already-registered","errorCode":null,"errorMessage":"Another strategy was already registered.","messagePattern":"Another strategy was already registered\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hystrix-core/src/main/java/com/netflix/hystrix/strategy/HystrixPlugins.java","lineNumber":152,"sourceCode":"            } else {\n                // we received an implementation from Archaius so use it\n                notifier.compareAndSet(null, (HystrixEventNotifier) impl);\n            }\n        }\n        return notifier.get();\n    }\n\n    /**\n     * Register a {@link HystrixEventNotifier} implementation as a global override of any injected or default implementations.\n     * \n     * @param impl\n     *            {@link HystrixEventNotifier} implementation\n     * @throws IllegalStateException\n     *             if called more than once or after the default was initialized (if usage occurs before trying to register)\n     */\n    public void registerEventNotifier(HystrixEventNotifier impl) {\n        if (!notifier.compareAndSet(null, impl)) {\n            throw new IllegalStateException(\"Another strategy was already registered.\");\n        }\n    }\n\n    /**\n     * Retrieve instance of {@link HystrixConcurrencyStrategy} to use based on order of precedence as defined in {@link HystrixPlugins} class header.\n     * <p>\n     * Override default by using {@link #registerConcurrencyStrategy(HystrixConcurrencyStrategy)} or setting property (via Archaius): <code>hystrix.plugin.HystrixConcurrencyStrategy.implementation</code> with the\n     * full classname to load.\n     * \n     * @return {@link HystrixConcurrencyStrategy} implementation to use\n     */\n    public HystrixConcurrencyStrategy getConcurrencyStrategy() {\n        if (concurrencyStrategy.get() == null) {\n            // check for an implementation from Archaius first\n            Object impl = getPluginImplementation(HystrixConcurrencyStrategy.class);\n            if (impl == null) {\n                // nothing set via Archaius so initialize with default\n                concurrencyStrategy.compareAndSet(null, HystrixConcurrencyStrategyDefault.getInstance());","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/Netflix/Hystrix/blob/5ce3bc58c38e7ca60ef2fe0e516e390e294ad941/hystrix-core/src/main/java/com/netflix/hystrix/strategy/HystrixPlugins.java#L134-L170","documentation":"HystrixPlugins stores global strategy implementations in AtomicReferences; registerEventNotifier(impl) succeeds only if the slot is empty (compareAndSet(null, impl)) — otherwise IllegalStateException('Another strategy was already registered.'). The same guard applies to all register* methods; registration also fails implicitly once the default/property-loaded implementation was fetched, because that instantiation occupies the slot.","triggerScenarios":"Calling HystrixPlugins.getInstance().registerEventNotifier(...) a second time, or registering after any code has already retrieved (and thereby lazily initialized) the event notifier — e.g. a first command executed before your registration runs.","commonSituations":"Two libraries/framework modules each registering their notifier (common in shared service templates); registering plugins in a non-deterministic @Configuration while metrics publishers already initialized; re-registrations in hot-reload/test contexts where HystrixPlugins retains state between test classes.","solutions":["Register every plugin exactly once, as early as possible (main()/contextCreated before any command executes)","When composing multiple behaviors, register a single composite notifier that delegates to all implementations instead of registering several","If already initialized, call Hystrix.reset() (resets plugins in newer versions) before re-registering — primarily a test-context tool","Check state defensively: plugins.getEventNotifier() instanceof default before registering to give a clearer error"],"exampleFix":"// before\nHystrixPlugins.getInstance().registerEventNotifier(a);\nHystrixPlugins.getInstance().registerEventNotifier(b); // ISE\n// after\nHystrixPlugins.getInstance().registerEventNotifier(new CompositeNotifier(a, b));\n// class CompositeNotifier extends HystrixEventNotifierDefault {\n//   ...delegate each callback to a and b... }","handlingStrategy":"validation","validationCode":"// before registering, confirm the slot is still open\nHystrixPlugins p = HystrixPlugins.getInstance();\nboolean slotOpen = (p.getEventNotifier() instanceof HystrixEventNotifierDefault); // default => unregistered\n// note: this check itself initializes the slot; do it only in diagnostics","typeGuard":"null","tryCatchPattern":"catch (IllegalStateException e) { if (\"Another strategy was already registered.\".equals(e.getMessage())) { // compose instead: wrap HystrixPlugins.getInstance().getEventNotifier() in a delegating notifier — but note re-registration is impossible; fix init order } }","preventionTips":["Register all plugins once, at the earliest startup point, before any command executes","Compose multiple behaviors into one delegating implementation instead of registering several","Call Hystrix.reset() between test suites that re-register plugins"],"tags":["java","hystrix","plugins","global-state","initialization-order"],"backgroundTag":null,"analyzedSha":"5ce3bc58c38e7ca60ef2fe0e516e390e294ad941","analyzedAt":"2026-08-14T10:55:35.600Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}