quarkusio/quarkus · error · java.lang.IllegalArgumentException
Invalid PURL qualifier
Error message
Invalid PURL qualifier
What it means
Thrown while parsing the qualifier section of a package URL (purl) string in Purl.parse: a key=value pair inside the qualifiers segment is malformed (missing '=' or empty key), so the qualifier cannot be decoded and the whole purl is rejected as invalid.
Source
Thrown at independent-projects/bootstrap/app-model/src/main/java/io/quarkus/sbom/Purl.java:151
name = percentDecode(namespaceName.substring(lastSlashIdx + 1));
namespace = decodePath(namespaceName.substring(0, lastSlashIdx));
}
String version = versionRaw != null && !versionRaw.isEmpty() ? percentDecode(versionRaw) : null;
Map<String, String> qualifiers = Map.of();
if (qualifiersRaw != null) {
TreeMap<String, String> parsed = null;
String singleKey = null;
String singleValue = null;
int pairStart = 0;
int len = qualifiersRaw.length();
while (pairStart <= len) {
int ampIdx = qualifiersRaw.indexOf('&', pairStart);
int pairEnd = ampIdx < 0 ? len : ampIdx;
int eqIdx = qualifiersRaw.indexOf('=', pairStart);
if (eqIdx < 0 || eqIdx > pairEnd) {
throw new IllegalArgumentException(
"Invalid PURL qualifier '" + qualifiersRaw.substring(pairStart, pairEnd)
+ "': missing '=' in " + purlString);
}
if (eqIdx == pairStart) {
throw new IllegalArgumentException(
"Invalid PURL qualifier '" + qualifiersRaw.substring(pairStart, pairEnd)
+ "': empty key in " + purlString);
}
String key = qualifiersRaw.substring(pairStart, eqIdx).toLowerCase();
String value = percentDecode(qualifiersRaw.substring(eqIdx + 1, pairEnd));
if (parsed != null) {
parsed.put(key, value);
} else if (singleKey != null) {
parsed = new TreeMap<>();
parsed.put(singleKey, singleValue);
parsed.put(key, value);
} else {
singleKey = key;View on GitHub (pinned to e1c734241f)
Solutions
- Add the missing '=' and value for the qualifier: ?key=value
- Remove qualifiers that have no value
- Validate the qualifier string matches key=value pairs joined by '&' before parsing
Example fix
// before
Purl.parse("pkg:maven/g/a@1.0?packaging");
// after
Purl.parse("pkg:maven/g/a@1.0?packaging=jar"); Defensive patterns
Strategy: validation
Validate before calling
for (String pair : qualifierPart.split("&")) { if (!pair.contains("=")) throw new IllegalArgumentException("Qualifier missing '=': " + pair); } Type guard
boolean validQualifiers(String q) { return java.util.Arrays.stream(q.split("&")).allMatch(p -> p.indexOf('=') > 0); } Try / catch
try { Purl.parse(purl); } catch (IllegalArgumentException e) { if (e.getMessage().contains("missing '='")) { fixQualifier(purl); } else { throw e; } } Prevention
- Always emit qualifiers as key=value pairs
- Validate purls at the boundary where they enter your system
- Avoid hand-building purls in scripts
When it happens
Trigger: Purl.parse() on a purl whose qualifier section has a key without '=', e.g. pkg:maven/g/a@1.0?packaging or ?a&b=1.
Common situations: Hand-assembled purl strings in CI scripts; SBOM data imported from non-conformant tools; typos in generated qualifiers.
Related errors
- Invalid PURL:
- type must not be empty
- name must not be empty
- Maven PURL is missing a namespace (groupId) for name (artifa
- PURL type must start with a letter:
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/81feb1642e5e1a8a.
Report an issue: GitHub.