provectus/kafka-ui · critical · IllegalArgumentException
OAuth2 authentication is enabled but no providers specified.
Error message
OAuth2 authentication is enabled but no providers specified.
What it means
When OAuth2 authentication is enabled, the clientRegistrationRepository bean converts configured OAuth providers into Spring ClientRegistrations. If the conversion yields an empty list — meaning auth was turned on but no providers were configured — it throws IllegalArgumentException at bean creation, failing context startup.
Solutions
- Define at least one OAuth2 provider (client-id, client-secret, issuer/scope) in the oauth properties
- Verify property keys match what OAuthPropertiesConverter expects for your version
- If OAuth2 is not needed, disable it instead of enabling with zero providers
Example fix
// before
auth:
type: OAUTH2
# no providers configured
// after
auth:
type: OAUTH2
oauth2:
client:
registration:
keycloak:
client-id: kafka-ui
client-secret: secret
scope: openid
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}' Defensive patterns
Strategy: validation
Validate before calling
if auth_type == 'OAUTH2':
providers = config.get('oauth2', {}).get('client', {}).get('registration', {})
if not providers:
raise ValueError('OAUTH2 enabled but no providers registered') Try / catch
try:
startApp()
except IllegalArgumentException as e:
if 'no providers specified' in str(e):
configureOAuthProvider() # supply client-id/secret/issuer then restart Prevention
- Pair every auth.type change with its required provider properties
- Templated deploys: fail early when OAUTH2 is on but provider env vars are empty
- Verify provider keys against the version's OAuthPropertiesConverter
When it happens
Trigger: Setting kafka-ui auth.type=OAUTH2 (or equivalent) without defining any providers under spring.security.oauth2.client.registration (or the kafka-ui oauth provider list).
Common situations: Enabling OAuth2 via env var but forgetting provider env vars; mis-typed provider property keys so the converter maps nothing; upgrade where provider config keys moved and old ones are silently ignored.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Application config isn't valid. Cluster names should be…
- Application config isn't valid. Two clusters can't have the…
- You specified username but do not specified password
- Invalid format for webclient.maxInMemoryBufferSize
- Schema Registry is not set for cluster
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/b55abb5b7ccc7cfb.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/auth/OAuthSecurityConfig.java:103
.flatMap(user -> {
var provider = getProviderByProviderId(request.getClientRegistration().getRegistrationId());
final var extractor = getExtractor(provider, acs);
if (extractor == null) {
return Mono.just(user);
}
return extractor.extract(acs, user, Map.of("request", request, "provider", provider))
.map(groups -> new RbacOAuth2User(user, groups));
});
}
@Bean
public InMemoryReactiveClientRegistrationRepository clientRegistrationRepository() {
final OAuth2ClientProperties props = OAuthPropertiesConverter.convertProperties(properties);
final List<ClientRegistration> registrations =
new ArrayList<>(new OAuth2ClientPropertiesMapper(props).asClientRegistrations().values());
if (registrations.isEmpty()) {
throw new IllegalArgumentException("OAuth2 authentication is enabled but no providers specified.");
}
return new InMemoryReactiveClientRegistrationRepository(registrations);
}
@Bean
public ServerLogoutSuccessHandler defaultOidcLogoutHandler(final ReactiveClientRegistrationRepository repository) {
return new OidcClientInitiatedServerLogoutSuccessHandler(repository);
}
@Nullable
private ProviderAuthorityExtractor getExtractor(final OAuthProperties.OAuth2Provider provider,
AccessControlService acs) {
Optional<ProviderAuthorityExtractor> extractor = acs.getOauthExtractors()
.stream()
.filter(e -> e.isApplicable(provider.getProvider(), provider.getCustomParams()))
.findFirst();
return extractor.orElse(null);View on GitHub (pinned to 83b5a60cc0)