{"record":{"id":"e545da760f856eb7","repo":"apereo/cas","slug":"loggingutils-warn-logger-e-e545da","errorCode":null,"errorMessage":"LoggingUtils.warn(LOGGER, e)","messagePattern":"LoggingUtils\\.warn\\(LOGGER, e\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-duo-core/src/main/java/org/apereo/cas/adaptors/duo/web/flow/action/DuoSecurityUniversalPromptValidateLoginAction.java","lineNumber":127,"sourceCode":"            browserSessionStore.getSessionAttributes(webContext).forEach((key, value) -> {\n                if (key.equalsIgnoreCase(FlowScope.class.getSimpleName())) {\n                    populateRequestContextScope(value, requestContext.getFlowScope());\n                } else if (key.equalsIgnoreCase(FlashScope.class.getSimpleName())) {\n                    populateRequestContextScope(value, requestContext.getFlashScope());\n                } else if (key.equalsIgnoreCase(RequestScope.class.getSimpleName())) {\n                    populateRequestContextScope(value, requestContext.getRequestScope());\n                } else if (key.equalsIgnoreCase(ConversationScope.class.getSimpleName())) {\n                    populateRequestContextScope(value, requestContext.getConversationScope());\n                } else {\n                    requestContext.getFlowScope().put(key, value);\n                }\n            });\n            populateContextWithCredential(requestContext, browserSessionStore);\n            populateContextWithAuthentication(requestContext, browserSessionStore);\n            populateContextWithService(requestContext, browserSessionStore);\n            return super.doExecuteInternal(requestContext);\n        } catch (final Throwable e) {\n            LoggingUtils.warn(LOGGER, e);\n        } finally {\n            if (browserSessionStore != null) {\n                val credential = (Credential) browserSessionStore.getSessionAttributes(webContext).get(Credential.class.getSimpleName());\n                WebUtils.putCredential(requestContext, credential);\n            }\n        }\n        return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_ERROR);\n    }\n\n    private static JEEContext toWebContext(final RequestContext requestContext) {\n        val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(requestContext);\n        val response = WebUtils.getHttpServletResponseFromExternalWebflowContext(requestContext);\n        return new JEEContext(request, response);\n    }\n\n    private static void populateRequestContextScope(final Object flowAttributes, final MutableAttributeMap<Object> requestContext) {\n        val mappedAttributes = new LinkedHashMap<>((Map) flowAttributes);\n        CollectionUtils.filter(mappedAttributes.values(), PredicateUtils.notNullPredicate());","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-duo-core/src/main/java/org/apereo/cas/adaptors/duo/web/flow/action/DuoSecurityUniversalPromptValidateLoginAction.java#L109-L145","documentation":"In DuoSecurityUniversalPromptValidateLoginAction, processStateFromBrowserStorage() (invoked from handleDuoSecurityUniversalPromptResponse while validating the Duo Universal Prompt response) wraps its work in try/catch(Throwable) and only logs the failure at WARN via LoggingUtils.warn(LOGGER, e). The exception is swallowed: no error transition is returned here, and the flow continues; the 'message' value shown is the logging call itself, meaning any downstream error surfaces only in logs.","triggerScenarios":"Any Throwable thrown while restoring Duo state from browser session storage and populating credential/authentication/service into the webflow context: corrupt or expired browser session store entries, deserialization failures of stored attributes, null/missing state from the Duo universal prompt round-trip.","commonSituations":"User's browser session/cookies expired between Duo prompt and callback; server restart wiped local session store; attributes stored in browserSessionStore fail to deserialize after a CAS upgrade; misconfigured session/cas.ticket… storage so stored attributes are absent.","solutions":["Reproduce with DEBUG/TRACE logging on org.apereo.cas.adaptors.duo and read the stack trace that LoggingUtils.warn emitted","Clear browser cookies/session state and retry the Duo universal prompt flow end to end","Verify the browser session store (e.g. session cookies / storage backend) is consistently configured across CAS nodes in a cluster","Check for version skew between nodes that could break deserialization of stored session attributes","If you need fail-closed behavior, override/extend the action to return the error transition instead of only logging"],"exampleFix":"// before\ncatch (final Throwable e) {\n    LoggingUtils.warn(LOGGER, e);\n}\n// after\ncatch (final Throwable e) {\n    LoggingUtils.error(LOGGER, e);\n    return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_ERROR);\n}","handlingStrategy":"try-catch","validationCode":"// Before invoking the flow action, confirm browser session store has Duo state:\nvar attrs = browserSessionStore.getSessionAttributes(webContext);\nif (!attrs.containsKey(Credential.class.getSimpleName())) {\n    // restart the Duo prompt flow instead of proceeding\n}","typeGuard":null,"tryCatchPattern":"try {\n    return processStateFromBrowserStorage(requestContext, browserSessionStore);\n} catch (Throwable e) {\n    LoggingUtils.warn(LOGGER, e);\n    return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_ERROR);\n}","preventionTips":["Keep session-store configuration consistent across all CAS nodes","Avoid CAS upgrades mid-session; version-skew breaks deserialization of stored attributes","Test the full Duo universal prompt round-trip after any session/cookie config change","Watch WARN logs from DuoSecurityUniversalPromptValidateLoginAction in production dashboards"],"tags":["duo","webflow","swallowed-exception","session"],"backgroundTag":"swallowed-exception","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"}