quarkusio/quarkus · error · IllegalStateException

Only one client ErrorInterceptor is supported

Error message

Only one client ErrorInterceptor is supported

What it means

WebSocketTelemetryProviderBuilder allows registering exactly one Function<String, ErrorInterceptor> that maps endpoint paths to client error interceptors. A second registration (when one is already set) throws this IllegalStateException because compositing interceptors is not implemented. The comment notes composite support may be added in the future.

Source

Thrown at extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/telemetry/WebSocketTelemetryProviderBuilder.java:117

    }

    void pathToServerErrorInterceptor(Function<String, ErrorInterceptor> pathToServerErrorInterceptor) {
        Objects.requireNonNull(pathToServerErrorInterceptor);
        if (this.pathToServerErrorInterceptor == null) {
            this.pathToServerErrorInterceptor = pathToServerErrorInterceptor;
        } else {
            // we can implement composite if we need this in the future
            throw new IllegalStateException("Only one server ErrorInterceptor is supported");
        }
    }

    void pathToClientErrorInterceptor(Function<String, ErrorInterceptor> pathToClientErrorInterceptor) {
        Objects.requireNonNull(pathToClientErrorInterceptor);
        if (this.pathToClientErrorInterceptor == null) {
            this.pathToClientErrorInterceptor = pathToClientErrorInterceptor;
        } else {
            // we can implement composite if we need this in the future
            throw new IllegalStateException("Only one client ErrorInterceptor is supported");
        }
    }

    void pathToServerSendingInterceptor(Function<String, SendingInterceptor> pathToServerSendingInterceptor) {
        Objects.requireNonNull(pathToServerSendingInterceptor);
        if (this.pathToServerSendingInterceptor == null) {
            this.pathToServerSendingInterceptor = pathToServerSendingInterceptor;
        } else {
            // we can implement composite if we need this in the future
            throw new IllegalStateException("Only one server SendingInterceptor is supported");
        }
    }

    void pathToClientSendingInterceptor(Function<String, SendingInterceptor> pathToClientSendingInterceptor) {
        Objects.requireNonNull(pathToClientSendingInterceptor);
        if (this.pathToClientSendingInterceptor == null) {
            this.pathToClientSendingInterceptor = pathToClientSendingInterceptor;
        } else {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure only one component registers pathToClientErrorInterceptor on the builder
  2. Merge your interceptor logic into a single Function before registering
  3. Check which extensions/features contribute interceptors and disable duplicates

Example fix

// before
builder.pathToClientErrorInterceptor(a);
builder.pathToClientErrorInterceptor(b); // throws
// after
builder.pathToClientErrorInterceptor(path -> path.startsWith("/ws") ? b.apply(path) : a.apply(path));
Defensive patterns

Strategy: validation

Validate before calling

if (builder.pathToClientErrorInterceptor != null) throw new IllegalStateException("already registered");

Try / catch

try { builder.pathToClientErrorInterceptor(fn); } catch (IllegalStateException e) { /* handle duplicate */ }

Prevention

When it happens

Trigger: Calling pathToClientErrorInterceptor(...) a second time after a Function has already been stored on the builder instance.

Common situations: Two telemetry/integration extensions (e.g. tracing + metrics) both registering their own client error interceptor via this runtime-builder API; duplicated initialization in application code or a repeated recorder callback.

Related errors


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