{"record":{"id":"18cc944494ccf513","repo":"quarkusio/quarkus","slug":"spiffe-id-must-have-a-non-root-path","errorCode":null,"errorMessage":"SPIFFE ID must have a non-root path: ","messagePattern":"SPIFFE ID must have a non-root path: ","errorType":"exception","errorClass":"SpiffeConnectionException","httpStatus":null,"severity":"error","filePath":"extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java","lineNumber":120,"sourceCode":"        String trustDomain = uri.getHost();\n        if (trustDomain == null || trustDomain.isEmpty()) {\n            throw new SpiffeConnectionException(\"SPIFFE ID must have a non-empty trust domain: \" + spiffeId);\n        }\n        if (trustDomain.length() > MAX_TRUST_DOMAIN_LENGTH) {\n            throw new SpiffeConnectionException(\"SPIFFE ID trust domain exceeds maximum length of \"\n                    + MAX_TRUST_DOMAIN_LENGTH + \" bytes: \" + spiffeId);\n        }\n        for (int i = 0; i < trustDomain.length(); i++) {\n            char c = trustDomain.charAt(i);\n            if (!isValidTrustDomainChar(c)) {\n                throw new SpiffeConnectionException(\n                        \"SPIFFE ID trust domain contains invalid character '\" + c + \"': \" + spiffeId);\n            }\n        }\n\n        String path = uri.getPath();\n        if (path == null || path.isEmpty() || \"/\".equals(path)) {\n            throw new SpiffeConnectionException(\"SPIFFE ID must have a non-root path: \" + spiffeId);\n        }\n        if (path.endsWith(\"/\")) {\n            throw new SpiffeConnectionException(\"SPIFFE ID path must not have a trailing slash: \" + spiffeId);\n        }\n        String[] segments = path.split(\"/\", -1);\n        for (int i = 1; i < segments.length; i++) {\n            String segment = segments[i];\n            if (segment.isEmpty()) {\n                throw new SpiffeConnectionException(\n                        \"SPIFFE ID path must not contain empty segments: \" + spiffeId);\n            }\n            if (\".\".equals(segment) || \"..\".equals(segment)) {\n                throw new SpiffeConnectionException(\n                        \"SPIFFE ID path must not contain dot segments: \" + spiffeId);\n            }\n            for (int j = 0; j < segment.length(); j++) {\n                char c = segment.charAt(j);\n                if (!isValidPathChar(c)) {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java#L102-L138","documentation":"A SPIFFE ID must include a workload path after the trust domain; 'spiffe://example.org' or 'spiffe://example.org/' identifies nothing. SpiffeValidator.validateSpiffeId throws SpiffeConnectionException when URI.getPath() is null, empty, or just '/'.","triggerScenarios":"validateSpiffeId invoked with 'spiffe://example.org' or 'spiffe://example.org/' — IDs taken from a CA certificate or config that only names the trust domain.","commonSituations":"Using the trust domain alone as a workload identity; truncated IDs from config placeholders; constructing the ID without the /ns/<namespace>/sa/<service-account> suffix expected by Kubernetes-style registries.","solutions":["Append the workload path, e.g. spiffe://example.org/ns/default/sa/app","Verify the SVID certificate's URI SAN includes a path component","Check config/templates so the full ID (domain + path) is generated, not just the domain"],"exampleFix":"// before\nString spiffeId = \"spiffe://example.org/\";\n// after\nString spiffeId = \"spiffe://example.org/ns/default/sa/app\";","handlingStrategy":"validation","validationCode":"static boolean hasWorkloadPath(String id) {\n    try {\n        String p = URI.create(id).getPath();\n        return p != null && p.length() > 1;\n    } catch (IllegalArgumentException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try { validator.validateSpiffeId(id); } catch (SpiffeConnectionException e) { throw new IllegalStateException(\"SPIFFE ID needs a workload path\", e); }","preventionTips":["Always generate full IDs including /ns/<ns>/sa/<sa> style paths","Never use a bare trust domain as a workload identity"],"tags":["spiffe","validation","path","spiffe-id"],"backgroundTag":"spiffe-id-validation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}