quarkusio/quarkus · error · SpiffeConnectionException
SPIFFE ID must not contain a fragment:
Error message
SPIFFE ID must not contain a fragment:
What it means
SPIFFE IDs may not contain a fragment (anything after '#'). SpiffeValidator.validateSpiffeId throws SpiffeConnectionException when URI.getFragment() != null, because the SPIFFE spec defines the ID strictly as scheme://trust-domain/path.
Source
Thrown at extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java:99
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
- Remove the '#fragment' portion of the ID
- If the fragment carries meaning, encode it as additional path segments instead
- Sanitize the source (config value, template, or SAN generator) that appends fragments
Example fix
// before String spiffeId = "spiffe://example.org/sa/app#prod"; // after String spiffeId = "spiffe://example.org/ns/prod/sa/app";
Defensive patterns
Strategy: validation
Validate before calling
static boolean hasNoFragment(String id) {
try { return URI.create(id).getFragment() == null; }
catch (IllegalArgumentException e) { return false; }
} Try / catch
try { validator.validateSpiffeId(id); } catch (SpiffeConnectionException e) { log.warnf("Fragment in SPIFFE ID: %s", id); } Prevention
- Trim everything from '#' when copying IDs from docs/HTML sources
- Never reuse web page URLs as workload identities
When it happens
Trigger: Passing an ID such as spiffe://example.org/sa/app#section to validateSpiffeId, or a certificate URI SAN containing a '#' fragment.
Common situations: Reusing HTML/doc URLs as identity strings; copy-paste carrying an anchor '#...' from documentation or issue trackers into config.
Related errors
- SPIFFE ID must not contain a port: ${spiffeId}
- SPIFFE ID must not contain a query:
- 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/8b821a0ea299f2c8.
Report an issue: GitHub.