apolloconfig/apollo · error · BadCredentialsException

Empty Username

Error message

Empty Username

What it means

Thrown by ApolloLdapAuthenticationProvider.authenticate() when the username extracted from the UsernamePasswordAuthenticationToken has zero length (checked via StringUtils.hasLength). This is a BadCredentialsException from Spring Security, mapping to HTTP 401. The message key 'LdapAuthenticationProvider.emptyUsername' is resolved from Spring Security message bundles, defaulting to 'Empty Username'.

Source

Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/ldap/ApolloLdapAuthenticationProvider.java:78

    super(authenticator);
    this.properties = properties;
  }

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,
        this.messages.getMessage("LdapAuthenticationProvider.onlySupports",
            "Only UsernamePasswordAuthenticationToken is supported"));
    UsernamePasswordAuthenticationToken userToken =
        (UsernamePasswordAuthenticationToken) authentication;
    String username = userToken.getName();
    String password = (String) authentication.getCredentials();
    if (this.logger.isDebugEnabled()) {
      this.logger.debug("Processing authentication request for user: " + username);
    }

    if (!StringUtils.hasLength(username)) {
      throw new BadCredentialsException(
          this.messages.getMessage("LdapAuthenticationProvider.emptyUsername", "Empty Username"));
    }
    if (!StringUtils.hasLength(password)) {
      throw new BadCredentialsException(this.messages
          .getMessage("AbstractLdapAuthenticationProvider.emptyPassword", "Empty Password"));
    }
    Assert.notNull(password, "Null password was supplied in authentication token");
    DirContextOperations userData = this.doAuthentication(userToken);
    String loginId = userData.getStringAttribute(properties.getMapping().getLoginId());
    UserDetails user = this.userDetailsContextMapper.mapUserFromContext(userData, loginId,
        this.loadUserAuthorities(userData, loginId, (String) authentication.getCredentials()));
    return this.createSuccessfulAuthentication(userToken, user);
  }
}

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Provide a non-empty username in the login form or authentication request.
  2. Add client-side validation to prevent form submission with an empty username.
  3. For API clients, ensure the Authorization header includes a valid username.

Example fix

// before — login submitted with empty username
// after — frontend validation
if (!username) { showFieldError('username', 'Username is required'); return; }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!StringUtils.hasLength(username)) {
    return ResponseEntity.badRequest().body("Username is required");
}

Type guard

static boolean hasNonEmptyUsername(String username) {
    return username != null && !username.trim().isEmpty();
}

Try / catch

try {
    authenticationManager.authenticate(
        new UsernamePasswordAuthenticationToken(username, password));
} catch (BadCredentialsException e) {
    if (e.getMessage().contains("Empty Username")) {
        return ResponseEntity.status(401).body("Username is required");
    }
    throw e;
}

Prevention

When it happens

Trigger: An authentication request is submitted to the Apollo portal login (backed by LDAP) where the username field is empty or null. The authenticate() method extracts userToken.getName() and, if it has no length, immediately rejects with BadCredentialsException before attempting any LDAP bind.

Common situations: Login form submitted with an empty username field. API client sends a Basic Auth header with no username portion. Automated health-check or monitor hitting the login endpoint without credentials. Frontend validation bypass or bug.

Related errors


AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14). Data as JSON: /api/errors/869e9c78f0f460b5. Report an issue: GitHub.