apereo/cas · info

No value could be retrieved from the header

Error message

No value could be retrieved from the header [{}]. Falling back to [{}].

What it means

BaseSpnegoKnownClientSystemsFilterAction determines the client's remote IP for SPNEGO decisions (e.g. checking whether the host is a known client system). When the configured alternativeRemoteHostAttribute header (e.g. X-Forwarded-For style custom header) yields nothing, it logs this warning and falls back to servlet request.getRemoteAddr(). It is informational: a fallback occurs, not a failure.

Solutions

  1. Verify the proxy/load balancer actually sends the configured header on every request path.
  2. Fix the header name in cas.authn.spnego.alternative-remote-host-attribute to match exactly what the proxy emits.
  3. If CAS is reachable directly, accept the getRemoteAddr() fallback or restrict direct access.
  4. Log/inspect incoming headers to confirm the expected header is present.

Example fix

// before
cas.authn.spnego.alternative-remote-host-attribute=X-CLIENT-IP
// after
cas.authn.spnego.alternative-remote-host-attribute=X-Forwarded-For
Defensive patterns

Strategy: fallback

Validate before calling

String ip = request.getHeader(altHeader);
if (ip == null || ip.isBlank()) ip = request.getRemoteAddr(); // same fallback CAS applies

Prevention

When it happens

Trigger: getRemoteIp is called with alternativeRemoteHostAttribute set (e.g. 'X-FORWARDED-FOR' or a custom header), but the incoming request lacks that header (blank value), so request.getRemoteAddr() is used instead.

Common situations: Requests bypassing the proxy that was supposed to set the alternative header (direct access, health checks); header name mismatch (wrong case/spacing) between config and what the proxy sends; load balancer not configured to forward client IP.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/080a9b2a4789fd92. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-spnego-webflow/src/main/java/org/apereo/cas/web/flow/client/BaseSpnegoKnownClientSystemsFilterAction.java:151

    /**
     * Pulls the remote IP from the current HttpServletRequest, or grabs the value
     * for the specified alternative attribute (say, for proxied requests).  Falls
     * back to providing the "normal" remote address if no value can be retrieved
     * from the specified alternative header value.
     *
     * @param context the context
     * @return the remote ip
     */
    private String getRemoteIp(final RequestContext context) {
        val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context);
        var userAddress = request.getRemoteAddr();
        LOGGER.debug("Remote Address = [{}]", userAddress);
        if (StringUtils.isNotBlank(this.alternativeRemoteHostAttribute)) {
            userAddress = request.getHeader(this.alternativeRemoteHostAttribute);
            LOGGER.debug("Header Attribute [{}] = [{}]", this.alternativeRemoteHostAttribute, userAddress);
            if (StringUtils.isBlank(userAddress)) {
                userAddress = request.getRemoteAddr();
                LOGGER.warn("No value could be retrieved from the header [{}]. Falling back to [{}].", this.alternativeRemoteHostAttribute, userAddress);
            }
        }
        return userAddress;
    }
}

View on GitHub (pinned to e7288fc434)