{"record":{"id":"daf0c03d90701816","repo":"quarkusio/quarkus","slug":"failed-to-locate-quarkus-extension-deployment-arti","errorCode":null,"errorMessage":"Failed to locate quarkus.extension.deployment-artifact in ${extPropsVisitUrl}","messagePattern":"Failed to locate quarkus\\.extension\\.deployment-artifact in (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/devui/deployment/src/main/java/io/quarkus/devui/deployment/DevUIProcessor.java","lineNumber":1070,"sourceCode":"        devUIWebJarProducer.produce(new DevUIWebJarBuildItem(deploymentKey, DEVUI));\n    }\n\n    private static GACT getDeploymentKey(ResolvedDependency runtimeExt) {\n        // Return null instead of throwing when the resource is not found in a given path tree root,\n        // so that MultiRootPathTree.apply() can continue searching the remaining roots.\n        final GACT result = runtimeExt.getContentTree().apply(BootstrapConstants.DESCRIPTOR_PATH, extPropsVisit -> {\n            if (extPropsVisit == null) {\n                return null;\n            }\n            final Properties props = new Properties();\n            try (BufferedReader reader = Files.newBufferedReader(extPropsVisit.getPath())) {\n                props.load(reader);\n            } catch (IOException e) {\n                throw new RuntimeException(\"Failed to read \" + extPropsVisit.getUrl(), e);\n            }\n            final String deploymentCoords = props.getProperty(BootstrapConstants.PROP_DEPLOYMENT_ARTIFACT);\n            if (deploymentCoords == null) {\n                throw new RuntimeException(\n                        \"Failed to locate \" + BootstrapConstants.PROP_DEPLOYMENT_ARTIFACT + \" in \" + extPropsVisit.getUrl());\n            }\n            var coords = GACTV.fromString(deploymentCoords);\n            return new GACT(coords.getGroupId(), coords.getArtifactId(), coords.getClassifier(), coords.getType());\n        });\n        if (result == null) {\n            throw new RuntimeException(\"Failed to locate \" + BootstrapConstants.DESCRIPTOR_PATH\n                    + \" in \" + runtimeExt.toCompactCoords());\n        }\n        return result;\n    }\n\n    @BuildStep(onlyIf = IsLocalDevelopment.class)\n    void createAllRoutes(WebJarResultsBuildItem webJarResultsBuildItem,\n            LaunchModeBuildItem launchModeBuildItem,\n            List<DevUIWebJarBuildItem> devUIWebJarBuiltItems,\n            BuildProducer<DevUIRoutesBuildItem> devUIRoutesProducer) {\n","sourceCodeStart":1052,"sourceCodeEnd":1088,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/devui/deployment/src/main/java/io/quarkus/devui/deployment/DevUIProcessor.java#L1052-L1088","documentation":"DevUIProcessor scans extension JARs for META-INF/quarkus.properties, which Quarkus extensions must ship to declare their deployment artifact coordinates. When the properties file exists but does not contain the quarkus.extension.deployment-artifact key, the build step throws this RuntimeException. It signals a malformed or non-compliant extension artifact on the application classpath.","triggerScenarios":"During Dev UI build steps, loading an extension's quarkus.properties succeeds but props.getProperty(BootstrapConstants.PROP_DEPLOYMENT_ARTIFACT) returns null — i.e. the descriptor file is present but missing the deployment-artifact entry.","commonSituations":"Using a locally built or hand-crafted extension JAR whose quarkus.properties was authored manually and omits the deployment artifact; an extension built with an old or non-Quarkus tooling setup; a repackaged/shaded JAR that stripped the property.","solutions":["Identify the offending extension from the URL in the message and regenerate/rebuild its JAR with the standard Quarkus extension parent POM so quarkus-maven-plugin populates quarkus.extension.deployment-artifact.","If authoring the descriptor manually, add a line like quarkus.extension.deployment-artifact=groupId:artifactId::jar:version to META-INF/quarkus.properties.","Remove or update the stale extension JAR from the classpath (check local ~/.m2 for outdated snapshots).","Run ./mvnw clean install on the extension module to ensure the descriptor is regenerated rather than copied from a stale build."],"exampleFix":"// before (META-INF/quarkus.properties in extension jar)\nquarkus.extension.name=My Ext\nquarkus.extension.description=...\n\n// after\nquarkus.extension.name=My Ext\nquarkus.extension.description=...\nquarkus.extension.deployment-artifact=com.example:my-ext-deployment::jar:1.0.0","handlingStrategy":"validation","validationCode":"Properties props = new Properties();\ntry (InputStream is = extPropsVisit.getUrl().openStream()) { props.load(is); }\nif (props.getProperty(\"quarkus.extension.deployment-artifact\") == null) {\n    throw new IllegalStateException(\"Extension descriptor missing deployment-artifact: \" + extPropsVisit.getUrl());\n}","typeGuard":null,"tryCatchPattern":"try { ... } catch (RuntimeException e) {\n    if (e.getMessage().contains(\"quarkus.extension.deployment-artifact\")) {\n        log.warnf(\"Skipping non-compliant extension: %s\", e.getMessage());\n    } else throw e;\n}","preventionTips":["Always build extensions with the Quarkus extension parent POM so the descriptor is generated","Verify extension JARs contain quarkus.extension.deployment-artifact before publishing","Keep runtime and deployment artifacts version-aligned via the Quarkus BOM"],"tags":["devui","quarkus-extension","build-time","missing-metadata"],"backgroundTag":"missing-extension-descriptor-property","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}