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

  1. Remove the clientId field from the update metadata (leave it null) — it is not updatable
  2. Fetch the current RegisteredClient and update only mutable fields (redirect URIs, grants, etc.)
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/531dcda0ff1a0dc4. Report an issue: GitHub.