quarkusio/quarkus · error · MojoExecutionException

Failed to parse ${extensionFile}

Error message

Failed to parse ${extensionFile}

What it means

readExtensionDescriptorFile reads the external extension descriptor file (extensionFile parameter) with Jackson into an ObjectNode. Any IOException — file missing, unreadable, or malformed JSON — is wrapped in a MojoExecutionException naming the file path, so the developer sees "Failed to parse <path>".

Source

Thrown at independent-projects/extension-maven-plugin/src/main/java/io/quarkus/maven/ExtensionDescriptorMojo.java:624

        }
        if (artifactNode == null || groupId == null || artifactId == null || version == null) {
            final ArtifactCoords coords = ArtifactCoords.jar(
                    groupId == null ? project.getGroupId() : groupId,
                    artifactId == null ? project.getArtifactId() : artifactId,
                    version == null ? project.getVersion() : version);
            extObject.put("artifact", coords.toString());
        }
    }

    private static String getRealValueOrNull(String s, String propertyExpr) {
        return s != null && !s.isBlank() && !s.equals(propertyExpr) ? s : null;
    }

    private ObjectNode readExtensionDescriptorFile(Path extensionFile, ObjectMapper mapper) throws MojoExecutionException {
        try (InputStream is = Files.newInputStream(extensionFile)) {
            return mapper.readValue(is, ObjectNode.class);
        } catch (IOException io) {
            throw new MojoExecutionException("Failed to parse " + extensionFile, io);
        }
    }

    private void completeCodestartArtifact(ObjectMapper mapper, ObjectNode extObject) throws MojoExecutionException {
        JsonNode mvalue = getJsonElement(extObject, METADATA, "codestart");
        if (mvalue == null || !mvalue.isObject()) {
            return;
        }
        final ObjectNode codestartObject = (ObjectNode) mvalue;
        mvalue = mvalue.get("artifact");
        if (mvalue == null) {
            if (!skipCodestartValidation) {
                throw new MojoExecutionException("Codestart artifact is missing from the " + extensionFile);
            }
            return;
        }

        String codestartArtifact = getCodestartArtifact(mvalue.asText(), project.getVersion());

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the extensionFile path exists and is readable (ls the exact path printed)
  2. Validate the JSON content (jq . extension.json) and fix syntax errors
  3. Check the wrapped IOException cause — FileNotFoundException vs JsonParseException — to distinguish path vs content problems

Example fix

// before: extension.json with trailing comma
{ "name": "myext", }
// after
{ "name": "myext" }
Defensive patterns

Strategy: validation

Validate before calling

Path f = Paths.get(configuredExtensionFile);
if (!Files.isReadable(f)) throw new IllegalStateException("extensionFile unreadable: " + f);
try (InputStream is = Files.newInputStream(f)) {
  new ObjectMapper().readTree(is); // throws if JSON is malformed
}

Try / catch

try {
  invoker.executeMaven("extension-descriptor");
} catch (MojoExecutionException e) {
  if (e.getMessage().startsWith("Failed to parse ")) { validateAndRepairJson(); }
  throw e;
}

Prevention

When it happens

Trigger: Executing extension-descriptor with a configured extensionFile that does not exist, cannot be opened, or contains invalid JSON that Jackson cannot map to ObjectNode.

Common situations: Wrong relative/absolute path for extensionFile config; truncated or hand-broken extension.json (trailing commas, stray text); BOM/encoding issues; file deleted between configuration and execution in CI.

Understand the failure class

Related errors


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