quarkusio/quarkus · error · SpiffeConnectionException

SPIFFE ID is not a valid URI: ${spiffeId}

Error message

SPIFFE ID is not a valid URI: ${spiffeId}

What it means

A SPIFFE ID must parse as a valid URI. SpiffeValidator.validateSpiffeId calls URI.create and wraps any IllegalArgumentException into a SpiffeConnectionException('SPIFFE ID is not a valid URI: ...'), so syntactically invalid strings (illegal characters, malformed scheme, etc.) are rejected with the original cause attached.

Source

Thrown at extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java:86

            throw new SpiffeConnectionException("SPIFFE ID must not be empty");
        }
        if (spiffeId.length() > MAX_SPIFFE_ID_LENGTH) {
            throw new SpiffeConnectionException("SPIFFE ID exceeds maximum length of " + MAX_SPIFFE_ID_LENGTH
                    + " bytes: " + spiffeId.length());
        }

        if (!spiffeId.startsWith(SPIFFE_URI_PREFIX)) {
            throw new SpiffeConnectionException("SPIFFE ID must have 'spiffe://' scheme: " + spiffeId);
        }
        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);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove or properly encode illegal characters from the SPIFFE ID (keeping in mind % is also forbidden).
  2. Trim whitespace/newlines from config-sourced values.
  3. Construct IDs only from validated trust-domain and path-segment values.

Example fix

// before
String id = "spiffe://" + trustDomain + "/ns/" + rawName.trim();
// after
String id = "spiffe://" + trustDomain + "/ns/" + sanitize(rawName); // [a-zA-Z0-9._-] only
Defensive patterns

Strategy: validation

Validate before calling

try {
    URI.create(spiffeId);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("SPIFFE ID is not a valid URI: " + spiffeId, e);
}

Try / catch

try {
    connection.establish();
} catch (SpiffeConnectionException e) {
    if (e.getMessage().contains("not a valid URI")) {
        log.error("SPIFFE ID contains illegal characters; sanitize identity input", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing strings with illegal URI characters (spaces, '<', '|', unencoded non-ASCII), or malformed syntax like spiffe://example.org:path or 'spiffe://example .org/x' to SPIFFE ID validation.

Common situations: Concatenating untrusted/user input into identity paths without sanitization; copy-paste errors introducing whitespace; config values with trailing characters or line breaks.

Related errors


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