{"record":{"id":"bfa04b4d3c734772","repo":"apereo/cas","slug":"unlimited-certificate-path-length-not-allowed-by-c","errorCode":null,"errorMessage":"Unlimited certificate path length not allowed by configuration.","messagePattern":"Unlimited certificate path length not allowed by configuration\\.","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-x509-core/src/main/java/org/apereo/cas/adaptors/x509/authentication/handler/support/X509CredentialsAuthenticationHandler.java","lineNumber":249,"sourceCode":"        this.revocationChecker.check(cert);\n\n        val pathLength = cert.getBasicConstraints();\n        if (pathLength < 0) {\n            if (!isCertificateAllowed(cert)) {\n                val msg = \"Certificate subject does not match pattern \" + this.regExSubjectDnPattern.pattern();\n                LOGGER.error(msg);\n                throw new FailedLoginException(msg);\n            }\n            if (this.checkKeyUsage && !isValidKeyUsage(cert)) {\n                val msg = \"Certificate keyUsage constraint forbids SSL client authentication.\";\n                LOGGER.error(msg);\n                throw new FailedLoginException(msg);\n            }\n        } else {\n            if (pathLength == Integer.MAX_VALUE && !this.maxPathLengthAllowUnspecified) {\n                val msg = \"Unlimited certificate path length not allowed by configuration.\";\n                LOGGER.error(msg);\n                throw new FailedLoginException(msg);\n            }\n            if (pathLength > this.maxPathLength && pathLength < Integer.MAX_VALUE) {\n                val msg = String.format(\"Certificate path length %s exceeds maximum value %s.\", pathLength, this.maxPathLength);\n                LOGGER.error(msg);\n                throw new FailedLoginException(msg);\n            }\n        }\n    }\n\n    /**\n     * Checks if is valid key usage. <p>\n     * KeyUsage ::= BIT STRING { digitalSignature (0), nonRepudiation (1),\n     * keyEncipherment (2), dataEncipherment (3), keyAgreement (4),\n     * keyCertSign (5), cRLSign (6), encipherOnly (7), decipherOnly (8) }\n     *\n     * @param certificate the certificate\n     * @return true, if  valid key usage\n     */","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-x509-core/src/main/java/org/apereo/cas/adaptors/x509/authentication/handler/support/X509CredentialsAuthenticationHandler.java#L231-L267","documentation":"X509CredentialsAuthenticationHandler.validate() bounds CA chain depth. For CA certificates (basicConstraints present) whose path length is Integer.MAX_VALUE (no explicit pathLenConstraint) and where maxPathLengthAllowUnspecified=false, the handler rejects the certificate because the chain depth is unbounded.","triggerScenarios":"A CA certificate with basicConstraints pathLength == Integer.MAX_VALUE is presented and cas.authn.x509.max-path-length-allow-unspecified=false.","commonSituations":"Root CAs without a pathLenConstraint are trusted issuers while strict path validation is configured; hardening config enabled maxPathLengthAllowUnspecified=false without realizing the root CA omits the constraint.","solutions":["Set cas.authn.x509.max-path-length-allow-unspecified=true to accept CA certs lacking an explicit pathLenConstraint.","Re-issue the CA certificate with an explicit pathLenConstraint extension.","Authenticate with an end-entity client certificate rather than a CA certificate.","Pair with a sensible maxPathLength value to keep depth bounded (see error 324)."],"exampleFix":"// before\ncas.authn.x509.max-path-length-allow-unspecified=false\n// after\ncas.authn.x509.max-path-length-allow-unspecified=true\ncas.authn.x509.max-path-length=5","handlingStrategy":"validation","validationCode":"int pl = cert.getBasicConstraints();\nif (pl == Integer.MAX_VALUE && !allowUnspecified) { reject(\"unbounded CA path\"); }","typeGuard":"boolean boundedPathAllowed(X509Certificate cert, boolean allowUnspecified) {\n    int pl = cert.getBasicConstraints();\n    return pl < 0 || pl != Integer.MAX_VALUE || allowUnspecified;\n}","tryCatchPattern":"try {\n    handler.authenticate(credential);\n} catch (FailedLoginException e) {\n    // unlimited path length rejected: set max-path-length-allow-unspecified=true or re-issue CA\n}","preventionTips":["Know whether your root CAs carry an explicit pathLenConstraint.","Set max-path-length-allow-unspecified deliberately, not accidentally.","Use end-entity certs for client authentication.","Audit CA certs with openssl x509 -text | grep pathlen."],"tags":["x509","certificate","path-length","configuration"],"backgroundTag":"certificate-path-length-too-deep","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}