{"record":{"id":"e4892ad614d551b1","repo":"apereo/cas","slug":"duo-returned-an-invalid-response-with-message","errorCode":null,"errorMessage":"Duo returned an Invalid response with message [{}] and detail [{}] when determining user account. This maybe a configuration error in the admin request and Duo will still be considered available.","messagePattern":"Duo returned an Invalid response with message \\[(.+?)\\] and detail \\[(.+?)\\] when determining user account\\. This maybe a configuration error in the admin request and Duo will still be considered available\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-duo-core/src/main/java/org/apereo/cas/adaptors/duo/authn/BaseDuoSecurityAuthenticationService.java","lineNumber":117,"sourceCode":"                val response = result.get(RESULT_KEY_RESPONSE);\n                val authResult = response.get(RESULT_KEY_RESULT).asString().toUpperCase(Locale.ENGLISH);\n\n                val status = DuoSecurityUserAccountStatus.valueOf(authResult);\n                account.setProviderId(properties.getId());\n                account.setStatus(status);\n                account.setMessage(response.get(RESULT_KEY_STATUS_MESSAGE).asString());\n                if (status == DuoSecurityUserAccountStatus.ENROLL) {\n                    val enrollUrl = response.get(RESULT_KEY_ENROLL_PORTAL_URL).asString();\n                    account.setEnrollPortalUrl(enrollUrl);\n                }\n            } else {\n                val code = result.get(RESULT_KEY_CODE).asInt();\n                if (code > RESULT_CODE_ERROR_THRESHOLD) {\n                    LOGGER.warn(\"Duo returned a failure response with code: [{}]. Duo will be considered unavailable\",\n                        result.get(RESULT_KEY_MESSAGE));\n                    throw new DuoSecurityException(\"Duo returned code %s: %s\".formatted(code, result.get(RESULT_KEY_MESSAGE)));\n                }\n                LOGGER.warn(\"Duo returned an Invalid response with message [{}] and detail [{}] \"\n                        + \"when determining user account. This maybe a configuration error in the admin request and Duo will \"\n                        + \"still be considered available.\",\n                    result.hasNonNull(RESULT_KEY_MESSAGE) ? result.get(RESULT_KEY_MESSAGE).asString() : StringUtils.EMPTY,\n                    result.hasNonNull(RESULT_KEY_MESSAGE_DETAIL) ? result.get(RESULT_KEY_MESSAGE_DETAIL).asString() : StringUtils.EMPTY);\n            }\n        } catch (final Exception e) {\n            LOGGER.warn(\"Reaching Duo has failed with error: [{}]\", e.getMessage(), e);\n            account.setStatus(DuoSecurityUserAccountStatus.UNAVAILABLE);\n        }\n\n        userAccountCachedMap.put(account.getUsername(), account);\n        LOGGER.debug(\"Fetched and cached duo user account [{}]\", account);\n        return account;\n    }\n\n    @Override\n    public Optional<DuoSecurityAdminApiService> getAdminApiService() {\n        if (StringUtils.isNotBlank(properties.getDuoAdminIntegrationKey()) && StringUtils.isNotBlank(properties.getDuoAdminSecretKey())) {","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-duo-core/src/main/java/org/apereo/cas/adaptors/duo/authn/BaseDuoSecurityAuthenticationService.java#L99-L135","documentation":"BaseDuoSecurityAuthenticationService.getUserAccount calls the Duo Admin API for a user account. If the HTTP response code is above the error threshold it throws DuoSecurityException, but for 'invalid' (non-failing) codes it logs this warning and still considers Duo available. It usually means the admin request reached Duo but the response was not a clean success — often a misconfigured admin integration key or permission.","triggerScenarios":"Duo Admin API responds with a non-success (but not fatal) status code along with a message/detail when querying a username, e.g. user not found in Duo directory or insufficient admin integration rights.","commonSituations":"Wrong or under-privileged Duo Admin API credentials, user absent from Duo, or Duo account configuration changes; developers see 'Duo returned an Invalid response...' in logs while the MFA flow still proceeds with UNAVAILABLE/other status.","solutions":["Verify the Duo Admin API integration key, secret key and hostname in cas.authn.mfa.duo properties","Confirm the admin integration has the required permissions (read user info) in the Duo admin console","Check whether the target username actually exists in the Duo directory","Enable CAS debug logging for org.apereo.cas.adaptors.duo to see the full response payload"],"exampleFix":"// before\ncas.authn.mfa.duo[0].admin-integration-key=wrong-ik\n// after\ncas.authn.mfa.duo[0].admin-integration-key=DI...\ncas.authn.mfa.duo[0].admin-secret-key=...\ncas.authn.mfa.duo[0].api-host=api-xxxx.duosecurity.com","handlingStrategy":"validation","validationCode":"// before deploy: verify Duo admin credentials\n// curl -H \"Authorization: Basic $B64(IK:SK)\" https://api-xxx.duosecurity.com/admin/v1/users/$user\ntypeGuard = null","typeGuard":null,"tryCatchPattern":"try { duoService.getUserAccount(username); } catch (DuoSecurityException e) { LOGGER.warn(\"Duo admin request rejected: {}\", e.getMessage()); /* treat duo as unavailable */ }","preventionTips":["Provision the Duo admin integration with correct permissions","Keep Duo keys in a secret store and rotate carefully","Test the admin API with curl during configuration","Monitor for this warn to detect silent misconfiguration"],"tags":["duo","mfa","api-response"],"backgroundTag":"http-error-response","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"}