quarkusio/quarkus · error · IllegalArgumentException
service interface descriptor file path cannot be null
Error message
service interface descriptor file path cannot be null
What it means
The same allProviders() factory validates that the service interface descriptor file Path is non-null, since it must read META-INF/services/<interface> lines from it. A null path is an immediate IllegalArgumentException before any I/O.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ServiceProviderBuildItem.java:49
private final List<String> providers;
/**
* Creates and returns a {@link ServiceProviderBuildItem} for the {@code serviceInterfaceClassName} by including
* all the providers that are listed in the service interface descriptor file.
*
* @param serviceInterfaceClassName the interface whose service interface descriptor file we want to embed
* @param serviceInterfaceDescriptorFile the path to the service interface descriptor file
* @return
* @throws IOException
*/
public static ServiceProviderBuildItem allProviders(final String serviceInterfaceClassName,
final Path serviceInterfaceDescriptorFile)
throws IOException {
if (serviceInterfaceClassName == null || serviceInterfaceClassName.trim().isEmpty()) {
throw new IllegalArgumentException("service interface name cannot be null or blank");
}
if (serviceInterfaceDescriptorFile == null) {
throw new IllegalArgumentException("service interface descriptor file path cannot be null");
}
final Set<String> classNames = new LinkedHashSet<>();
final List<String> lines = Files.readAllLines(serviceInterfaceDescriptorFile, StandardCharsets.UTF_8);
// parse each line and add each listed provider
for (String line : lines) {
final int commentIndex = line.indexOf('#');
if (commentIndex >= 0) {
// strip off anything after the # (including the #)
line = line.substring(0, commentIndex);
}
line = line.trim();
if (!line.isEmpty()) {
classNames.add(line);
}
}
return new ServiceProviderBuildItem(serviceInterfaceClassName, List.copyOf(classNames), false);
}
View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the descriptor file exists on the build classpath and pass its real Path
- Or use allProvidersFromClassPath(serviceInterfaceClassName) which resolves the resource itself
- Guard the path with Objects.requireNonNull before calling
Example fix
// before
ServiceProviderBuildItem.allProviders("com.example.MySpi", path); // path may be null
// after
if (path == null) throw new IllegalStateException("descriptor missing on classpath");
ServiceProviderBuildItem.allProviders("com.example.MySpi", path); Defensive patterns
Strategy: validation
Validate before calling
Objects.requireNonNull(descriptorPath, "descriptor path required");
if (!Files.exists(descriptorPath)) throw new IllegalStateException("descriptor missing: " + descriptorPath); Prevention
- Check ClassLoader.getResource(...) results for null before converting to a Path
- Prefer allProvidersFromClassPath when the descriptor is a classpath resource
- Verify the provider JAR is a build dependency
When it happens
Trigger: Calling ServiceProviderBuildItem.allProviders(iface, null), typically when the resource lookup that should produce the Path returned null.
Common situations: Trying to locate the descriptor via ClassLoader.getResource which returned null (resource not on the build classpath) and forwarding null; a build-step config option left unset.
Related errors
- service interface name cannot be null or blank
- Could not read class path resources having path '${resourceP
- The serviceDescriptorFile interface cannot be blank
- The provider class name cannot be null or blank
- Unable to copy json config file from ${jsonPath} to ${thinJa
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5929647e1537dfd5.
Report an issue: GitHub.