gradle/gradle · error · InvalidIvyPublicationException
supplied %s does not match ivy descriptor (cannot edit %1$s
Error message
supplied %s does not match ivy descriptor (cannot edit %1$s directly in the ivy descriptor file).
What it means
Before upload, ValidatingIvyPublisher re-parses the generated ivy.xml and compares its identity fields (organisation, module name, revision) with the publication coordinates. IvyFieldValidator.matches throws this when a field differs: identity fields cannot be changed by editing the ivy descriptor file.
Source
Thrown at platforms/software/ivy/src/main/java/org/gradle/api/publish/ivy/internal/publisher/ValidatingIvyPublisher.java:160
private void checkCanPublish(String name, IvyArtifact artifact) {
File artifactFile = artifact.getFile();
if (artifactFile.isDirectory()) {
throw new InvalidIvyPublicationException(name, String.format("artifact file is a directory: '%s'", artifactFile));
}
}
private IvyFieldValidator field(IvyNormalizedPublication publication, String name, String value) {
return new IvyFieldValidator(publication.getName(), name, value);
}
private static class IvyFieldValidator extends PublicationFieldValidator<IvyFieldValidator> {
private IvyFieldValidator(String publicationName, String name, String value) {
super(IvyFieldValidator.class, publicationName, name, value);
}
public IvyFieldValidator matches(String expectedValue) {
if (!value.equals(expectedValue)) {
throw new InvalidIvyPublicationException(publicationName,
String.format("supplied %s does not match ivy descriptor (cannot edit %1$s directly in the ivy descriptor file).", name)
);
}
return this;
}
@Override
protected InvalidUserDataException failure(String message) {
throw new InvalidIvyPublicationException(publicationName, message);
}
}
}
View on GitHub (pinned to 534f27719b)
Solutions
- Set organisation/module/revision on the IvyPublication itself, never via withXml
- Delete the stale descriptor and regenerate: ./gradlew clean generateDescriptorFileForIvyPublication
- Remove any withXml block that rewrites <info> identity and mirror the change on publication properties
Example fix
// before
publication.descriptor.withXml {
asNode().info[0].'@organisation' = 'com.correct' // rejected at publish time
}
// after
publication.organisation = 'com.correct' Defensive patterns
Strategy: validation
Validate before calling
gradle.taskGraph.whenReady { graph ->
def pub = publishing.publications.findByName('ivy')
if (pub != null && graph.hasTask(pub.publishTasks.first())) {
assert pub.organisation == project.group : 'publication organisation drifted from project.group'
assert pub.revision == project.version.toString() : 'publication revision drifted from project.version'
}
} Prevention
- Treat ivy.xml identity as generated output - never edit it directly
- Derive publication coordinates from one source (project.group/version) and set them on the publication
- Run clean builds in CI so stale descriptors cannot be published
When it happens
Trigger: publication.descriptor.withXml rewriting the <info> organisation/module/revision attributes; changing publication.organisation/version after the descriptor was generated; a stale ivy.xml left in the build directory from an earlier configuration; hand-editing the generated descriptor between generation and publish.
Common situations: Scripts that patch descriptor identity via withXml instead of setting publication properties; CI reusing a dirty build directory after changing project version or coordinates; plugins that rewrite ivy.xml metadata.
Related errors
- impossible to publish {} using {}: no artifact pattern defin
- Invalid ivy extra info element name: '%s'
- Cannot add an extra info element with null element name
- Cannot add an extra info element with null namespace
- Ivy publication '%s' cannot include multiple components
AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22).
Data as JSON: /api/errors/dcceb74167337061.
Report an issue: GitHub.