quarkusio/quarkus · error · OidcClientException
Only 'refresh_token' grant is supported, please call OidcCli
Error message
Only 'refresh_token' grant is supported, please call OidcClient#refreshTokens method instead
What it means
OidcClientImpl.getTokens() performs a client_credentials/password-style token grant using pre-built tokenGrantParams. If those params are null (the client was built only with a refresh grant), the only supported flow is refresh, and callers must use refreshTokens() instead — hence this OidcClientException.
Source
Thrown at extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientImpl.java:108
this.tokenRevokeUri = tokenRevokeUri;
this.tokenGrantParams = tokenGrantParams;
this.commonRefreshGrantParams = commonRefreshGrantParams;
this.grantType = grantType;
this.oidcConfig = oidcClientConfig;
this.requestFilters = requestFilters;
this.responseFilters = responseFilters;
this.clientSecretBasicAuthScheme = clientCredentials.clientSecretBasicAuthScheme;
this.jwtAssertionProvided = clientCredentials.jwtAssertionProvided;
this.clientJwtKey = jwtAssertionProvided ? null : clientCredentials.clientJwtKey;
this.clientSecret = clientCredentials.clientSecret;
this.clientAssertionProvider = clientCredentials.clientAssertionProvider;
}
@Override
public Uni<Tokens> getTokens(Map<String, String> additionalGrantParameters) {
checkClosed();
if (tokenGrantParams == null) {
throw new OidcClientException(
"Only 'refresh_token' grant is supported, please call OidcClient#refreshTokens method instead");
}
return getJsonResponse(OidcEndpoint.Type.TOKEN, tokenGrantParams, additionalGrantParameters, Operation.GET);
}
@Override
public Uni<Tokens> refreshTokens(String refreshToken, Map<String, String> additionalGrantParameters) {
checkClosed();
if (refreshToken == null) {
throw new OidcClientException("Refresh token is null");
}
MultiMap refreshGrantParams = copyMultiMap(commonRefreshGrantParams);
refreshGrantParams.add(OidcConstants.REFRESH_TOKEN_VALUE, refreshToken);
return getJsonResponse(OidcEndpoint.Type.TOKEN, refreshGrantParams, additionalGrantParameters, Operation.REFRESH);
}
@Override
public Uni<Boolean> revokeAccessToken(String accessToken, Map<String, String> additionalParameters) {View on GitHub (pinned to e1c734241f)
Solutions
- Call oidcClient.refreshTokens(refreshToken, params) instead of getTokens().
- If getTokens() is required, configure a supported initial grant, e.g. quarkus.oidc-client.grant.type=client (client_credentials).
- Obtain the initial refresh token from another client/flow and only use this client for refresh operations.
Example fix
// before Tokens t = oidcClient.getTokens().await().indefinitely(); // after Tokens t = oidcClient.refreshTokens(refreshToken, Map.of()).await().indefinitely();
Defensive patterns
Strategy: validation
Validate before calling
if (client instanceof OidcClientImpl && isRefreshOnlyClient(config)) {
// must use refreshTokens(), not getTokens()
} Type guard
boolean supportsTokenGrant(OidcClientConfig cfg) {
return !"refresh".equals(cfg.grant().type().orElse(GrantType.CLIENT).toString());
} Try / catch
try {
return client.getTokens(params);
} catch (OidcClientException e) {
if (e.getMessage().contains("refresh_token")) {
return client.refreshTokens(storedRefreshToken, params);
}
throw e;
} Prevention
- Match the API call to the configured grant type.
- Configure grant.type=client if you need getTokens().
- Centralize token acquisition in one helper that knows the client's grant.
When it happens
Trigger: Calling oidcClient.getTokens(...) on an OidcClient configured without a grant type that produces token grant params (i.e. no client_credentials / password grant configured), so tokenGrantParams == null.
Common situations: Configuring quarkus.oidc-client.<name>.grant.type=refresh (or leaving only refresh params) and then calling getTokens() directly; calling getTokens() on a client intended solely for refreshing tokens.
Related errors
- A generic type is not allowed here; try creating a subclass
- Build item class must be leaf (final) types: %s
- Cannot construct empty build items
- A build step must be a non-static method: %s
- Not supported for JTA entity managers
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/68e854d5f6652d0d.
Report an issue: GitHub.