gradle/gradle · warning
%s: Could not find plugin descriptor of %s at META-INF/gradl
Error message
%s: Could not find plugin descriptor of %s at META-INF/gradle-plugins/%s.properties
What it means
For every gradlePlugin.plugins declaration, validation expects a matching descriptor file named <id>.properties in META-INF/gradle-plugins inside the jar. DECLARED_PLUGIN_MISSING_MESSAGE fires when the declaration exists but no such file name was collected: the declaration and the jar contents are out of sync.
Source
Thrown at platforms/extensibility/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/JavaGradlePluginPlugin.java:388
descriptorURI = descriptor.getPropertiesFileUrl().toURI();
} catch (URISyntaxException e) {
// Do nothing since the only side effect is that we wouldn't
// be able to log the plugin descriptor file name. Shouldn't
// be a reasonable scenario where this occurs since these
// descriptors should be generated from real files.
}
String pluginFileName = descriptorURI != null ? new File(descriptorURI).getName() : "UNKNOWN";
pluginFileNames.add(pluginFileName);
String pluginImplementation = descriptor.getImplementationClassName();
if (pluginImplementation.length() == 0) {
LOGGER.warn(String.format(INVALID_DESCRIPTOR_WARNING_MESSAGE, task.getPath(), pluginFileName));
} else if (!hasFullyQualifiedClass(pluginImplementation)) {
LOGGER.warn(String.format(BAD_IMPL_CLASS_WARNING_MESSAGE, task.getPath(), pluginFileName, pluginImplementation));
}
}
for (PluginDeclaration declaration : plugins.get()) {
if (!pluginFileNames.contains(declaration.getId() + ".properties")) {
LOGGER.warn(String.format(DECLARED_PLUGIN_MISSING_MESSAGE, task.getPath(), declaration.getName(), declaration.getId()));
}
}
}
}
boolean hasFullyQualifiedClass(String fqClass) {
return actionsState.getCollectedClasses().contains(fqClass.replaceAll("\\.", "/") + ".class");
}
}
/**
* A file copy action that collects plugin descriptors as they are added to the jar.
*/
static class PluginDescriptorCollectorAction implements Action<FileCopyDetails> {
private final PluginValidationActionsState actionsState;
PluginDescriptorCollectorAction(PluginValidationActionsState actionsState) {
this.actionsState = actionsState;View on GitHub (pinned to 534f27719b)
Solutions
- Align the declaration id with the descriptor file name: id 'com.example.greeting' must produce META-INF/gradle-plugins/com.example.greeting.properties.
- Undo source-set or processResources customizations that exclude or relocate generated descriptors.
- Build the jar and list META-INF/gradle-plugins to see which files actually shipped.
- Re-run ./gradlew validatePlugins to confirm every declaration maps to a file.
Example fix
// before: declaration id does not match shipped descriptor
gradlePlugin {
plugins {
create('greeting') { id = 'com.example.greet' } // expects com.example.greet.properties
}
}
// jar contains META-INF/gradle-plugins/com.example.greeting.properties
// after: make them match
create('greeting') { id = 'com.example.greeting' } Defensive patterns
Strategy: validation
Validate before calling
tasks.register('checkDescriptorIds') {
dependsOn jar
doLast {
new ZipFile(jar.archiveFile.get().asFile).withCloseable { zf ->
gradlePlugin.plugins.each { d ->
def entry = "META-INF/gradle-plugins/${d.id}.properties"
if (zf.getEntry(entry) == null) {
throw new GradleException("declaration ${d.id} has no ${entry} in jar")
}
}
}
}
} Prevention
- Keep declaration ids exactly equal to the descriptor file base name.
- Do not customize processResources or source sets in ways that exclude generated descriptors.
- Inspect the jar's META-INF/gradle-plugins directory whenever descriptor wiring changes.
When it happens
Trigger: Declaring a plugin with an id while descriptor generation or placement was customized away (processResources/source set changes), the id in the declaration not matching the generated file name, or resources re-routed so the .properties never lands in the jar.
Common situations: Custom processResources or sourceSets configuration breaking descriptor generation; renaming plugin ids without regenerating descriptors; disabling the generate-plugin-descriptors output.
Related errors
- %s: No valid plugin descriptors were found in META-INF/gradl
- %s: A plugin descriptor was found for %s but it was invalid.
- %s: A valid plugin descriptor was found for %s but the imple
- Problem group name must not be blank
- Problem group displayName must not be blank
AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22).
Data as JSON: /api/errors/336c3e43e8627c98.
Report an issue: GitHub.