{"record":{"id":"389c7b94908a1341","repo":"apereo/cas","slug":"spnego-authorization-header-does-not-begin-wi","errorCode":null,"errorMessage":"SPNEGO Authorization header [{}] does not begin with the prefix [{}]","messagePattern":"SPNEGO Authorization header \\[(.+?)\\] does not begin with the prefix \\[(.+?)\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-spnego-webflow/src/main/java/org/apereo/cas/web/flow/SpnegoCredentialsAction.java","lineNumber":76,"sourceCode":"            request.getHeader(HttpHeaders.AUTHORIZATION),\n            request.getHeader(HttpHeaders.AUTHORIZATION.toLowerCase(Locale.ENGLISH)));\n        LOGGER.debug(\"SPNEGO Authorization header located as [{}]\", authorizationHeader);\n        if (StringUtils.isBlank(authorizationHeader)) {\n            LOGGER.warn(\"SPNEGO Authorization header is not found under [{}]\", HttpHeaders.AUTHORIZATION);\n            return null;\n        }\n\n        val authzHeaderLength = authorizationHeader.length();\n        val prefixLength = SpnegoConstants.NEGOTIATE.length();\n        if (authzHeaderLength > prefixLength && authorizationHeader.startsWith(SpnegoConstants.NEGOTIATE)) {\n            LOGGER.debug(\"SPNEGO Authorization header found with [{}] bytes\", authzHeaderLength - prefixLength);\n            val base64 = authorizationHeader.substring(prefixLength);\n            val token = EncodingUtils.decodeBase64(base64);\n            val tokenString = new String(token, Charset.defaultCharset());\n            LOGGER.debug(\"Obtained token: [{}]. Creating credential...\", tokenString);\n            return new SpnegoCredential(token);\n        }\n        LOGGER.warn(\"SPNEGO Authorization header [{}] does not begin with the prefix [{}]\",\n            authorizationHeader, SpnegoConstants.NEGOTIATE);\n        return null;\n    }\n\n    @Override\n    protected void onError(final RequestContext context) {\n        setResponseHeader(context);\n    }\n\n    @Override\n    protected void onSuccess(final RequestContext context) {\n        setResponseHeader(context);\n    }\n\n    /**\n     * Sets the response header based on the retrieved token.\n     *\n     * @param context the context","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-spnego-webflow/src/main/java/org/apereo/cas/web/flow/SpnegoCredentialsAction.java#L58-L94","documentation":"After locating an Authorization header, SpnegoCredentialsAction requires it to start with the 'Negotiate' scheme prefix before Base64-decoding the SPNEGO token. If the header uses another scheme (Basic, Bearer, NTLM, wrong casing handled by the strict startsWith), it logs this warning and returns null. CAS thus refuses to treat the token as a Kerberos credential.","triggerScenarios":"Authorization header present but does not start with SpnegoConstants.NEGOTIATE ('Negotiate'), e.g. header is 'Basic ...', 'Bearer ...', 'NTLM ...', or a malformed 'Negotiate' spelling/casing mismatch within the first prefixLength chars, in constructCredentialsFromRequest.","commonSituations":"App behind CAS already sent Basic auth credentials that win the header race; client sends NTLM instead of Kerberos Negotiate; custom gateway rewriting the header; misconfigured client library sending Bearer tokens to the CAS login URL.","solutions":["Make the client send 'Authorization: Negotiate <base64-token>' exactly, with the Negotiate prefix and a single space.","Remove/fix any filter or proxy that injects Basic/Bearer Authorization headers before CAS SPNEGO handling.","Check the client's authentication provider (e.g. force Kerberos over NTLM in the browser or HTTP client).","Verify SpnegoConstants.NEGOTIATE casing matches what the client sends if a custom constant was configured."],"exampleFix":"// before\nrequest.setHeader(\"Authorization\", \"Bearer \" + token);\n// after\nrequest.setHeader(\"Authorization\", \"Negotiate \" + base64(spnegoToken));","handlingStrategy":"validation","validationCode":"String authz = request.getHeader(\"Authorization\");\nif (authz == null || !authz.startsWith(\"Negotiate \")) {\n    throw new IllegalArgumentException(\"Expected 'Authorization: Negotiate <token>'\");\n}","typeGuard":"static boolean isNegotiateScheme(String header) {\n    return header != null && header.regionMatches(true, 0, \"Negotiate \", 0, 10);\n}","tryCatchPattern":null,"preventionTips":["Send exact 'Negotiate <base64>' scheme in clients","Audit filters/proxies that rewrite Authorization","Prefer Kerberos over NTLM in client config"],"tags":["spnego","http-header","kerberos","auth-scheme"],"backgroundTag":"invalid-argument-format","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"}