quarkusio/quarkus · error · RuntimeException

Quarkus extension deployment artifact does not appear to de

Error message

Quarkus extension deployment artifact  does not appear to depend on the corresponding runtime artifact 

What it means

After injecting the deployment artifact's dependency graph, Quarkus verifies the deployment's dependency on the corresponding runtime artifact survived resolution (presentInTargetGraph, set during replaceRuntimeExtensionNodes). If the runtime artifact node was not found among the deployment's dependencies, this RuntimeException is thrown — meaning the deployment artifact does not actually (transitively, in scope, non-conflicted) depend on its runtime counterpart.

Source

Thrown at independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/ApplicationDependencyResolver.java:1009

            extDeps.add(dep);
        }

        private void collectDeploymentDeps() {
            log.debugf("Collecting dependencies of %s", info.deploymentArtifact);
            deploymentNode = collectDependencies(info.deploymentArtifact, exclusions, runtimeNode.getRepositories());
            if (deploymentNode.getChildren().isEmpty()) {
                throw new RuntimeException(
                        "Failed to collect dependencies of " + deploymentNode.getArtifact()
                                + ": either its POM could not be resolved from the available Maven repositories "
                                + "or the artifact does not have any dependencies while at least a dependency on the runtime artifact "
                                + info.runtimeArtifact + " is expected");
            }
            ensureScopeAndOptionality(deploymentNode, runtimeNode.getDependency().getScope(),
                    runtimeNode.getDependency().isOptional());

            replaceRuntimeExtensionNodes(deploymentNode);
            if (!presentInTargetGraph) {
                throw new RuntimeException(
                        "Quarkus extension deployment artifact " + deploymentNode.getArtifact()
                                + " does not appear to depend on the corresponding runtime artifact "
                                + info.runtimeArtifact);
            }
        }

        private void injectDeploymentDependency(AppDep parent) {
            // if the parent is an extension then add the deployment node as a dependency of the parent's deployment node
            // (that would happen when injecting conditional dependencies)
            // otherwise, the runtime module is going to be replaced with the deployment node
            final DependencyNode parentDeploymentNode = parent == null ? null
                    : (parent.ext == null ? null : parent.ext.deploymentNode);
            if (parentDeploymentNode == null) {
                runtimeNode.setData(QUARKUS_RUNTIME_ARTIFACT, runtimeNode.getArtifact());
                runtimeNode.setArtifact(deploymentNode.getArtifact());
                runtimeNode.setChildren(deploymentNode.getChildren());
                if (parent != null) {
                    dependencyMap.getOrCreate(parent.node.getArtifact()).putDependency(deploymentNode.getDependency());

View on GitHub (pinned to e1c734241f)

Solutions

  1. Inspect the deployment POM: ensure the runtime artifact is a direct, non-optional, compile-scope dependency without exclusions.
  2. Run 'mvn dependency:tree -f <deployment-pom>' and confirm the runtime artifact appears; fix exclusion/scope/version if missing.
  3. Check dependencyManagement/imported BOMs for a managed version of the runtime artifact that conflicts with the one Quarkus expects; align versions.
  4. If using a locally-built extension, mvn install both runtime and deployment modules at the same version so they resolve consistently.

Example fix

<!-- before: runtime dep marked optional -->
<dependency>
  <groupId>com.acme</groupId>
  <artifactId>myext</artifactId>
  <optional>true</optional>
</dependency>
<!-- after: mandatory runtime dependency -->
<dependency>
  <groupId>com.acme</groupId>
  <artifactId>myext</artifactId>
</dependency>
Defensive patterns

Strategy: validation

Validate before calling

// verify runtime artifact present in deployment module's tree before building
Process p = new ProcessBuilder("mvn", "-f", "myext-deployment/pom.xml",
    "dependency:tree").inheritIO().start();
p.waitFor();
// grep output for the runtime artifactId 'myext' (non-optional, present)

Prevention

When it happens

Trigger: collectDeploymentDeps() calls replaceRuntimeExtensionNodes(deploymentNode); if no node in the deployment graph matched the runtime artifact's key, presentInTargetGraph stays false and the error is thrown for the deployment artifact / runtime artifact pair.

Common situations: A custom deployment POM declaring the runtime dependency as optional, provided-scope filtered out, or with a different version excluded by dependencyManagement conflict rules; the runtime artifact excluded via Maven <exclusions>; version mismatch resolved to a different coordinate than info.runtimeArtifact.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/d51cb5a6bc4a199c. Report an issue: GitHub.