apereo/cas · warning
Duo returned an Invalid response with message
Error message
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. What it means
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.
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
Example fix
// before cas.authn.mfa.duo[0].admin-integration-key=wrong-ik // after cas.authn.mfa.duo[0].admin-integration-key=DI... cas.authn.mfa.duo[0].admin-secret-key=... cas.authn.mfa.duo[0].api-host=api-xxxx.duosecurity.com
Defensive patterns
Strategy: validation
Validate before calling
// before deploy: verify Duo admin credentials // curl -H "Authorization: Basic $B64(IK:SK)" https://api-xxx.duosecurity.com/admin/v1/users/$user typeGuard = null
Try / catch
try { duoService.getUserAccount(username); } catch (DuoSecurityException e) { LOGGER.warn("Duo admin request rejected: {}", e.getMessage()); /* treat duo as unavailable */ } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Invalid response format received from Duo
- Duo returned code
- Unknown Duo Security authentication attempt
- Duo Security passcode authentication has failed
- Duo Security universal prompt authentication has failed
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/e4892ad614d551b1.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-duo-core/src/main/java/org/apereo/cas/adaptors/duo/authn/BaseDuoSecurityAuthenticationService.java:117
val response = result.get(RESULT_KEY_RESPONSE);
val authResult = response.get(RESULT_KEY_RESULT).asString().toUpperCase(Locale.ENGLISH);
val status = DuoSecurityUserAccountStatus.valueOf(authResult);
account.setProviderId(properties.getId());
account.setStatus(status);
account.setMessage(response.get(RESULT_KEY_STATUS_MESSAGE).asString());
if (status == DuoSecurityUserAccountStatus.ENROLL) {
val enrollUrl = response.get(RESULT_KEY_ENROLL_PORTAL_URL).asString();
account.setEnrollPortalUrl(enrollUrl);
}
} else {
val code = result.get(RESULT_KEY_CODE).asInt();
if (code > RESULT_CODE_ERROR_THRESHOLD) {
LOGGER.warn("Duo returned a failure response with code: [{}]. Duo will be considered unavailable",
result.get(RESULT_KEY_MESSAGE));
throw new DuoSecurityException("Duo returned code %s: %s".formatted(code, result.get(RESULT_KEY_MESSAGE)));
}
LOGGER.warn("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.",
result.hasNonNull(RESULT_KEY_MESSAGE) ? result.get(RESULT_KEY_MESSAGE).asString() : StringUtils.EMPTY,
result.hasNonNull(RESULT_KEY_MESSAGE_DETAIL) ? result.get(RESULT_KEY_MESSAGE_DETAIL).asString() : StringUtils.EMPTY);
}
} catch (final Exception e) {
LOGGER.warn("Reaching Duo has failed with error: [{}]", e.getMessage(), e);
account.setStatus(DuoSecurityUserAccountStatus.UNAVAILABLE);
}
userAccountCachedMap.put(account.getUsername(), account);
LOGGER.debug("Fetched and cached duo user account [{}]", account);
return account;
}
@Override
public Optional<DuoSecurityAdminApiService> getAdminApiService() {
if (StringUtils.isNotBlank(properties.getDuoAdminIntegrationKey()) && StringUtils.isNotBlank(properties.getDuoAdminSecretKey())) {View on GitHub (pinned to e7288fc434)