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
- Build XML with the node API (asNode().appendNode(...)) instead of appending raw strings
- Escape injected text (&, <, >) or set values via the node API, then clean and regenerate: ./gradlew clean generatePomFileForMavenPublication
- 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
- Generate XML via the node API (asNode().appendNode) rather than string concatenation
- Escape free text injected through withXml
- Never hand-edit generated POMs under build/publications - rerun generatePomFile instead
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
- project must be the root tag
- Maven publication '%s' cannot include multiple components
- Cannot publish a dependency with an artifact name different
- Unsupported dependency type: {}
- Artifact {} wasn't produced by this build.
AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22).
Data as JSON: /api/errors/d65959cf509fb403.
Report an issue: GitHub.