{"record":{"id":"0fbb853d792d3aea","repo":"apereo/cas","slug":"link-is-not-valid-and-is-not-part-of-the-inte","errorCode":null,"errorMessage":"Link [{}] is not valid and is not part of the interrupt response","messagePattern":"Link \\[(.+?)\\] is not valid and is not part of the interrupt response","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"support/cas-server-support-interrupt-webflow/src/main/java/org/apereo/cas/interrupt/webflow/actions/FinalizeInterruptFlowAction.java","lineNumber":52,"sourceCode":"                .map(service -> service.getAccessStrategy().getUnauthorizedRedirectUrl())\n                .orElse(null);\n            if (accessUrl != null) {\n                val url = accessUrl.toURL().toExternalForm();\n                val externalContext = requestContext.getExternalContext();\n                externalContext.requestExternalRedirect(url);\n                externalContext.recordResponseComplete();\n                return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_STOP);\n            }\n            LOGGER.warn(\"Interrupt response has blocked the authentication flow\");\n            throw UnauthorizedServiceException.denied(\"Rejected\");\n        }\n\n        if (requestContext.getRequestParameters().contains(\"link\")) {\n            val link = requestContext.getRequestParameters().get(\"link\");\n            LOGGER.debug(\"Finalizing interrupt flow with link [{}]\", link);\n            val validLink = response.getLinks().containsValue(link);\n            if (!validLink) {\n                LOGGER.warn(\"Link [{}] is not valid and is not part of the interrupt response\", link);\n                throw UnauthorizedServiceException.denied(\"Rejected\");\n            }\n        }\n        \n        val authentication = WebUtils.getAuthentication(requestContext);\n        interruptTrackingEngine.trackInterrupt(requestContext, response);\n        WebUtils.putAuthentication(authentication, requestContext);\n        WebUtils.putInterruptAuthenticationFlowFinalized(requestContext);\n        return success();\n    }\n}\n","sourceCodeStart":34,"sourceCodeEnd":64,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-interrupt-webflow/src/main/java/org/apereo/cas/interrupt/webflow/actions/FinalizeInterruptFlowAction.java#L34-L64","documentation":"FinalizeInterruptFlowAction validates any 'link' request parameter the user clicked after the interrupt screen against the links recorded in the stored interrupt response. If the link is not one of the response's links, CAS warns 'Link [{}] is not valid and is not part of the interrupt response' and throws UnauthorizedServiceException.denied(\"Rejected\").","triggerScenarios":"Replaying/forging a 'link' request parameter to the interrupt finalize endpoint, or a link URL in the registered service's interrupt configuration that does not match what was rendered/recorded in the response.","commonSituations":"Bookmarked stale links after interrupt messages changed, service definitions updated so old links are no longer valid, or probing attempts trying to redirect elsewhere.","solutions":["Retry the interrupt flow from the beginning so a fresh, valid response with current links is generated","Verify link URLs configured for the service interrupt match exactly what the user clicks","Clear stale interrupt tracking state/bookmarks after updating interrupt messages","Treat repeated occurrences as potential malicious probing and review access logs"],"exampleFix":"// before (link updated but user hits old bookmark)\nGET /cas/login?service=...&link=https://old.example.com\n// after (user restarts flow and clicks current link)\nGET /cas/login?service=...&link=https://current.example.com","handlingStrategy":"validation","validationCode":"val validLink = interruptResponse.getLinks().containsValue(link);\nif (!validLink) { /* do not follow the link; restart the interrupt flow */ }","typeGuard":null,"tryCatchPattern":"try { finalizeFlow(requestContext); } catch (UnauthorizedServiceException e) { restartInterruptFlow(); }","preventionTips":["Never bookmark interrupt link URLs","Ensure configured link URLs exactly match rendered links","Regenerate the flow after changing interrupt messages","Log repeated invalid link attempts as suspicious"],"tags":["interrupt","webflow","unauthorized","link-validation"],"backgroundTag":"permission-denied","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"}