quarkusio/quarkus · error · OidcClientRegistrationException
Client id can not be modified
Error message
Client id can not be modified
What it means
RegisteredClientImpl.update validates that the new client metadata does not change immutable fields. If the submitted ClientMetadata contains a clientId that differs from the registered one, it throws OidcClientRegistrationException 'Client id can not be modified' before issuing any HTTP request, because OIDC dynamic client registration (RFC 7592) treats client_id as immutable.
Source
Thrown at extensions/oidc-client-registration/runtime/src/main/java/io/quarkus/oidc/client/registration/runtime/RegisteredClientImpl.java:90
@Override
public Uni<RegisteredClient> read() {
checkClosed();
checkClientRequestUri();
HttpRequest<Buffer> request = client.getAbs(registrationClientUri);
request.putHeader(HttpHeaders.ACCEPT.toString(), APPLICATION_JSON);
OidcRequestContextProperties requestProps = getRequestProps();
return makeRequest(requestProps, request, Buffer.buffer())
.transformToUni(resp -> newRegisteredClient(resp, requestProps));
}
@Override
public Uni<RegisteredClient> update(ClientMetadata newMetadata) {
checkClosed();
checkClientRequestUri();
if (newMetadata.getClientId() != null && !registeredMetadata.getClientId().equals(newMetadata.getClientId())) {
throw new OidcClientRegistrationException("Client id can not be modified");
}
if (newMetadata.getClientSecret() != null
&& !registeredMetadata.getClientSecret().equals(newMetadata.getClientSecret())) {
throw new OidcClientRegistrationException("Client secret can not be modified");
}
JsonObjectBuilder builder = jsonProvider().createObjectBuilder();
JsonObject newJsonObject = newMetadata.getJsonObject();
JsonObject currentJsonObject = registeredMetadata.getJsonObject();
LOG.debugf("Current client metadata: %s", currentJsonObject.toString());
// Try to ensure the same order of properties as in the original metadata
for (Map.Entry<String, JsonValue> entry : currentJsonObject.entrySet()) {
if (PRIVATE_PROPERTIES.contains(entry.getKey())) {
continue;
}View on GitHub (pinned to e1c734241f)
Solutions
- Remove the clientId field from the update metadata (leave it null) — it is not updatable
- Fetch the current RegisteredClient and update only mutable fields (redirect URIs, grants, etc.)
- If a new client_id is genuinely needed, perform a fresh registration instead of an update
Example fix
// before
ClientMetadata meta = ClientMetadata.builder().clientId("other-id").redirectUris(...).build();
client.update(meta); // throws
// after
ClientMetadata meta = ClientMetadata.builder() // no clientId set
.redirectUris(List.of("https://app.example.com/cb"))
.build();
client.update(meta); Defensive patterns
Strategy: validation
Validate before calling
if (newMetadata.getClientId() != null && !registeredClientId.equals(newMetadata.getClientId())) {
throw new IllegalArgumentException("clientId is immutable; omit it from update metadata");
} Type guard
static boolean isUpdatable(ClientMetadata registered, ClientMetadata update) {
return update.getClientId() == null || registered.getClientId().equals(update.getClientId());
} Try / catch
try {
client.update(newMetadata).await().indefinitely();
} catch (OidcClientRegistrationException e) {
if (e.getMessage().startsWith("Client id can not be modified")) {
// rebuild metadata without clientId and retry once
} else throw e;
} Prevention
- Never copy clientId from other clients into update metadata
- Build update metadata fresh with only mutable fields
- Treat client_id and client_secret as immutable per RFC 7592
When it happens
Trigger: Calling update(newMetadata) where newMetadata.getClientId() is non-null and different from registeredMetadata.getClientId().
Common situations: Copying metadata from another client into an update call, loading metadata from a config/JSON where client_id drifted after re-registration, or serializing/deserializing metadata incorrectly.
Related errors
- Client secret can not be modified
- Registered OIDC Client can not make requests to the client c
- Failed to generate key id
- Application 'web-app' type is only supported if access token
- Failed to parse the realm name.
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/531dcda0ff1a0dc4.
Report an issue: GitHub.