{"record":{"id":"5adf2a97a4f73475","repo":"quarkusio/quarkus","slug":"spiffe-id-path-must-not-contain-empty-segments","errorCode":null,"errorMessage":"SPIFFE ID path must not contain empty segments: ","messagePattern":"SPIFFE ID path must not contain empty segments: ","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":129,"sourceCode":"            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)) {\n                    throw new SpiffeConnectionException(\n                            \"SPIFFE ID path contains invalid character '\" + c + \"': \" + spiffeId);\n                }\n            }\n        }\n    }\n\n    private static String extractOptionalUriSan(X509Certificate cert) {\n        try {","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java#L111-L147","documentation":"SPIFFE ID paths must not contain empty segments, i.e. consecutive slashes or a leading double slash. SpiffeValidator.validateSpiffeId throws SpiffeConnectionException when splitting the path on '/' yields an empty segment.","triggerScenarios":"validateSpiffeId invoked with IDs like 'spiffe://example.org//sa/app' or 'spiffe://example.org/ns//app' — produced by double slashes from path concatenation.","commonSituations":"Joining path pieces where one piece already ends with '/' and the next begins with '/'; environment variables or config values with stray slashes; URL-normalization code that inserts extra separators.","solutions":["Collapse duplicate '/' separators so each path segment is non-empty","Normalize before building: path.replaceAll(\"/+\", \"/\") on the path portion","Fix the string-concatenation/template producing the doubled slash"],"exampleFix":"// before\nString spiffeId = domain + \"/\" + namespace + \"/\" + sa; // domain already ends with '/'\n// after\nString spiffeId = (domain.endsWith(\"/\") ? domain : domain + \"/\") + namespace + \"/\" + sa;","handlingStrategy":"validation","validationCode":"static String collapseSlashes(String id) {\n    int i = id.indexOf(\"://\") + 3;\n    int pathStart = id.indexOf('/', i);\n    if (pathStart < 0) return id;\n    return id.substring(0, pathStart) + id.substring(pathStart).replaceAll(\"/+\", \"/\");\n}","typeGuard":null,"tryCatchPattern":"try { validator.validateSpiffeId(id); } catch (SpiffeConnectionException e) { log.warnf(\"Empty path segment in SPIFFE ID: %s\", id); }","preventionTips":["Collapse duplicate '/' when concatenating path pieces","Check each interpolated config value for stray leading/trailing slashes"],"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"}