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

  1. Add the missing '=' and value for the qualifier: ?key=value
  2. Remove qualifiers that have no value
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/81feb1642e5e1a8a. Report an issue: GitHub.