quarkusio/quarkus · error · SpiffeConnectionException
SPIFFE ID must not contain a query:
Error message
SPIFFE ID must not contain a query:
What it means
SPIFFE IDs are plain URIs of the form spiffe://trust-domain/path and may not carry a query string. SpiffeValidator.validateSpiffeId rejects any ID whose URI has a query component (anything after '?'), throwing SpiffeConnectionException.
Source
Thrown at extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java:96
if (spiffeId.contains("%")) {
throw new SpiffeConnectionException("SPIFFE ID must not contain percent-encoded characters: " + spiffeId);
}
URI uri;
try {
uri = URI.create(spiffeId);
} catch (IllegalArgumentException e) {
throw new SpiffeConnectionException("SPIFFE ID is not a valid URI: " + spiffeId, e);
}
if (uri.getUserInfo() != null) {
throw new SpiffeConnectionException("SPIFFE ID must not contain userinfo: " + spiffeId);
}
if (uri.getPort() != -1) {
throw new SpiffeConnectionException("SPIFFE ID must not contain a port: " + spiffeId);
}
if (uri.getQuery() != null) {
throw new SpiffeConnectionException("SPIFFE ID must not contain a query: " + spiffeId);
}
if (uri.getFragment() != null) {
throw new SpiffeConnectionException("SPIFFE ID must not contain a fragment: " + spiffeId);
}
String trustDomain = uri.getHost();
if (trustDomain == null || trustDomain.isEmpty()) {
throw new SpiffeConnectionException("SPIFFE ID must have a non-empty trust domain: " + spiffeId);
}
if (trustDomain.length() > MAX_TRUST_DOMAIN_LENGTH) {
throw new SpiffeConnectionException("SPIFFE ID trust domain exceeds maximum length of "
+ MAX_TRUST_DOMAIN_LENGTH + " bytes: " + spiffeId);
}
for (int i = 0; i < trustDomain.length(); i++) {
char c = trustDomain.charAt(i);
if (!isValidTrustDomainChar(c)) {
throw new SpiffeConnectionException(
"SPIFFE ID trust domain contains invalid character '" + c + "': " + spiffeId);View on GitHub (pinned to e1c734241f)
Solutions
- Strip everything from '?' onward and use only spiffe://<trust-domain>/<path>
- Move environment/metadata into the path segments (e.g. /ns/prod/sa/app) instead of query params
- Fix the certificate issuance/registration template that generates the URI SAN
Example fix
// before String spiffeId = "spiffe://example.org/sa/app?env=prod"; // after String spiffeId = "spiffe://example.org/ns/prod/sa/app";
Defensive patterns
Strategy: validation
Validate before calling
static boolean hasNoQuery(String id) {
try { return URI.create(id).getQuery() == null; }
catch (IllegalArgumentException e) { return false; }
} Try / catch
try { validator.validateSpiffeId(id); } catch (SpiffeConnectionException e) { throw new IllegalArgumentException("SPIFFE ID must not contain '?'", e); } Prevention
- Encode metadata as path segments, never query parameters
- Strip query strings when deriving IDs from URLs
- Review templates that interpolate full URLs into ID fields
When it happens
Trigger: Calling validateSpiffeId with an ID like spiffe://example.org/service?env=prod, or supplying a certificate whose URI SAN includes query parameters.
Common situations: Building SPIFFE IDs from template URLs that already contain query strings; concatenating '?param=value' metadata onto IDs; tooling that serializes full request URLs as workload identities.
Related errors
- SPIFFE ID must not contain a port: ${spiffeId}
- SPIFFE ID must not contain a fragment:
- SPIFFE ID exceeds maximum length of 2048 bytes: ${length}
- SPIFFE ID must have 'spiffe://' scheme: ${spiffeId}
- SPIFFE ID is not a valid URI: ${spiffeId}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d8da1ac1ffdd104a.
Report an issue: GitHub.