gradle/gradle · error · InvalidMavenPublicationException

POM file is invalid. Check any modifications you have made t

Error message

POM file is invalid. Check any modifications you have made to the POM file.

What it means

ValidatingMavenPublisher re-parses the generated POM with Maven's Xpp3 reader before upload. An XmlPullParserException means the POM file is not well-formed XML, so the publication is aborted with InvalidMavenPublicationException.

Source

Thrown at platforms/software/maven/src/main/java/org/gradle/api/publish/maven/internal/publisher/ValidatingMavenPublisher.java:80

                .validMavenIdentifier();
        MavenFieldValidator versionValidator = field(publication, "version", publication.getVersion())
                .notEmpty()
                .validInFileName();

        if (!hasParentPom) {
            groupIdValidator.matches(model.getGroupId());
            versionValidator.matches(model.getVersion());
        }
    }

    private Model parsePomFileIntoMavenModel(MavenNormalizedPublication publication) {
        File pomFile = publication.getPomArtifact().getFile();
        try {
            Model model = readModelFromPom(pomFile);
            model.setPomFile(pomFile);
            return model;
        } catch (XmlPullParserException parseException) {
            throw new InvalidMavenPublicationException(publication.getName(),
                    "POM file is invalid. Check any modifications you have made to the POM file.",
                    parseException);
        } catch (IOException ex) {
            throw UncheckedException.throwAsUncheckedException(ex);
        }
    }

    @SuppressWarnings("DefaultCharset")
    private Model readModelFromPom(File pomFile) throws IOException, XmlPullParserException {
        // Note: source files can have non-UTF8 encoding. FileReader uses default Charset and also handles invalid characters.
        try (FileReader reader = new FileReader(pomFile)) {
            return new MavenXpp3Reader().read(reader);
        }
    }

    private void validateArtifacts(MavenNormalizedPublication publication) {
        for (MavenArtifact artifact : publication.getAllArtifacts()) {
            field(publication, "artifact extension", artifact.getExtension())

View on GitHub (pinned to 534f27719b)

Solutions

  1. Build XML with the node API (asNode().appendNode(...)) instead of appending raw strings
  2. Escape injected text (&, <, >) or set values via the node API, then clean and regenerate: ./gradlew clean generatePomFileForMavenPublication
  3. Never hand-edit files under build/publications - treat them as outputs and rerun the generator

Example fix

// before
pom.withXml { asString().append('<description>AT&T tools</description>') } // unescaped &

// after
pom.withXml {
    def root = asNode()
    if (root.description.isEmpty()) root.appendNode('description')
    root.description[0].value = 'AT&T tools'
}
Defensive patterns

Strategy: validation

Validate before calling

import groovy.xml.XmlSlurper
tasks.withType(GenerateMavenPom).configureEach {
    doLast {
        new XmlSlurper().parse(outputFile) // throws immediately if the POM is not well-formed
    }
}

Try / catch

try {
    new XmlSlurper().parse(pomFile)
} catch (org.xml.sax.SAXException e) {
    // fix the withXml block that injects raw text; escape & and <
}

Prevention

When it happens

Trigger: pom.withXml injecting raw strings with unescaped & or < characters; manually editing the generated pom-default.xml under build/publications/ between generation and publish; tools or plugins corrupting the generated file.

Common situations: withXml blocks using asString().append(...) with free text containing & or <; developers hand-patching generated POMs instead of the DSL; encoding problems in injected text.

Related errors


AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22). Data as JSON: /api/errors/d65959cf509fb403. Report an issue: GitHub.