{"record":{"id":"d214662d979ae93c","repo":"junit-team/junit5","slug":"failed-to-create-forkjoinpool","errorCode":null,"errorMessage":"Failed to create ForkJoinPool","messagePattern":"Failed to create ForkJoinPool","errorType":"exception","errorClass":"JUnitException","httpStatus":null,"severity":"critical","filePath":"junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java","lineNumber":111,"sourceCode":"\t\tthis(configuration, TaskEventListener.NOOP);\n\t}\n\n\tForkJoinPoolHierarchicalTestExecutorService(ParallelExecutionConfiguration configuration,\n\t\t\tTaskEventListener taskEventListener) {\n\t\tforkJoinPool = createForkJoinPool(configuration);\n\t\tthis.taskEventListener = taskEventListener;\n\t\tparallelism = forkJoinPool.getParallelism();\n\t\tLoggerFactory.getLogger(getClass()).config(() -> \"Using ForkJoinPool with parallelism of \" + parallelism);\n\t}\n\n\tprivate ForkJoinPool createForkJoinPool(ParallelExecutionConfiguration configuration) {\n\t\ttry {\n\t\t\treturn new ForkJoinPool(configuration.getParallelism(), new WorkerThreadFactory(), null, false,\n\t\t\t\tconfiguration.getCorePoolSize(), configuration.getMaxPoolSize(), configuration.getMinimumRunnable(),\n\t\t\t\tconfiguration.getSaturatePredicate(), configuration.getKeepAliveSeconds(), TimeUnit.SECONDS);\n\t\t}\n\t\tcatch (Exception cause) {\n\t\t\tthrow new JUnitException(\"Failed to create ForkJoinPool\", cause);\n\t\t}\n\t}\n\n\t@Override\n\tpublic Future<@Nullable Void> submit(TestTask testTask) {\n\t\tExclusiveTask exclusiveTask = new ExclusiveTask(testTask);\n\t\tif (!isAlreadyRunningInForkJoinPool()) {\n\t\t\t// ensure we're running inside the ForkJoinPool so we\n\t\t\t// can use ForkJoinTask API in invokeAll etc.\n\t\t\treturn forkJoinPool.submit(exclusiveTask);\n\t\t}\n\t\t// Limit the amount of queued work so we don't consume dynamic tests too eagerly\n\t\t// by forking only if the current worker thread's queue length is below the\n\t\t// desired parallelism. This optimistically assumes that the already queued tasks\n\t\t// can be stolen by other workers and the new task requires about the same\n\t\t// execution time as the already queued tasks. If the other workers are busy,\n\t\t// the parallelism is already at its desired level. If all already queued tasks\n\t\t// can be stolen by otherwise idle workers and the new task takes significantly","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java#L93-L129","documentation":"Wraps any exception thrown while constructing the java.util.concurrent.ForkJoinPool used by ForkJoinPoolHierarchicalTestExecutorService. The pool is built from a ParallelExecutionConfiguration (parallelism, core/max pool size, minimum runnable, saturate predicate, keep-alive). If the JDK rejects those parameters (e.g. illegal parallelism, negative sizes, or an UnsupportedOperation from the configuration source) the original cause is chained.","triggerScenarios":"The engine creates its executor service and calls createForkJoinPool(configuration); ForkJoinPool's constructor throws IllegalArgumentException or IllegalStateException because configuration.getParallelism()/getCorePoolSize()/getMaxPoolSize()/getMinimumRunnable() returned inconsistent values, or parallelism <= 0, or maxPoolSize < parallelism, or a saturate predicate implementation fails.","commonSituations":"Misconfigured junit.execution.parallel.config.* properties (e.g. parallelism=0, maxPoolSize smaller than parallelism, minimumRunnable negative); a custom ParallelExecutionConfigurationSupplier returning bad values; running on a JVM/JDK where ForkJoinPool constructor semantics changed; resource starvation where a pool cannot be allocated.","solutions":["Inspect the chained cause: it states which configuration value was illegal.","Check junit.execution.parallel.config.* properties in junit-platform.properties: ensure parallelism >= 1, maxPoolSize >= parallelism, corePoolSize >= 1, minimumRunnable >= 0.","If using a custom org.junit.platform.engine.support.hierarchical.ParallelExecutionConfigurationSupplier, validate its returned ParallelExecutionConfiguration values.","Temporarily disable parallel execution (junit.execution.parallel.enabled=false) to confirm the config is the culprit."],"exampleFix":"// before (junit-platform.properties)\njunit.execution.parallel.enabled=true\njunit.execution.parallel.config.fixed.parallelism=0\njunit.execution.parallel.config.fixed.max-pool-size=1\n// after\njunit.execution.parallel.enabled=true\njunit.execution.parallel.config.fixed.parallelism=4\njunit.execution.parallel.config.fixed.max-pool-size=4","handlingStrategy":"validation","validationCode":"// Validate parallel config before launching\nint p = readInt(\"junit.execution.parallel.config.fixed.parallelism\", 1);\nint max = readInt(\"junit.execution.parallel.config.fixed.max-pool-size\", p);\nint core = readInt(\"junit.execution.parallel.config.fixed.core-pool-size\", p);\nif (p < 1 || max < p || core < 1) throw new IllegalArgumentException(\"bad parallel config\");","typeGuard":null,"tryCatchPattern":"try {\n    launcher.execute(request);\n} catch (JUnitException e) {\n    Throwable c = e.getCause();\n    if (c instanceof JUnitException jc && jc.getMessage().contains(\"Failed to create ForkJoinPool\")) {\n        // fix junit.execution.parallel.config.* and retry\n    }\n    throw e;\n}","preventionTips":["Keep maxPoolSize >= parallelism >= 1 and corePoolSize >= 1 in junit-platform.properties.","Unit-test custom ParallelExecutionConfigurationSupplier outputs for valid ranges.","Disable parallel execution when diagnosing to isolate config issues."],"tags":["parallel-execution","forkjoinpool","configuration","executor-service"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}