apache/iceberg · warning

Unknown error handler

Error message

Unknown error handler {}, response body won't be parsed

What it means

HTTPClient.throwFailure() only interprets response bodies when the configured error handler is an ErrorHandler instance. For any other handler type it logs this warning, skips body parsing, and builds a generic ErrorResponse from the status code and raw body.

Solutions

  1. Use an ErrorHandler (e.g. ErrorHandlers.defaultErrorHandler()) when configuring the HTTP client.
  2. Migrate custom Function-based handlers to extend/implement ErrorHandler and override parseResponse.
  3. Align client and catalog dependency versions so the same handler API is used.
  4. If the raw-body fallback is acceptable, treat the warn as informational.

Example fix

// before
HTTPClient.builder().withErrorMapper(code -> "HTTP " + code).build();
// after
HTTPClient.builder().withErrorHandler(ErrorHandlers.defaultErrorHandler()).build();
Defensive patterns

Strategy: type-guard

Type guard

if (!(handler instanceof ErrorHandler)) { handler = ErrorHandlers.defaultErrorHandler(); }

Try / catch

try { restClient.post(path, body, ErrorHandler.class.cast(handler)); } catch (RESTException e) { /* fallback ErrorResponse still carries status + raw body */ }

Prevention

When it happens

Trigger: Using HTTPClient with a custom/legacy Function<Integer, String> error handler (pre-ErrorHandler API) or passing a non-ErrorHandler mapper, then receiving a non-2xx response.

Common situations: Code written against the older REST client API, custom client builders injecting their own handler type, mixing client versions where the handler interface changed.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/c6464c0010b6b645. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/rest/HTTPClient.java:214

        .responseCode(response.getCode())
        .withMessage(message)
        .withType(type)
        .build();
  }

  // Process a failed response through the provided errorHandler, and throw a RESTException if the
  // provided error handler doesn't already throw.
  private static void throwFailure(
      ClassicHttpResponse response, String responseBody, Consumer<ErrorResponse> errorHandler) {
    ErrorResponse errorResponse = null;

    if (responseBody != null) {
      try {
        if (errorHandler instanceof ErrorHandler) {
          errorResponse =
              ((ErrorHandler) errorHandler).parseResponse(response.getCode(), responseBody);
        } else {
          LOG.warn(
              "Unknown error handler {}, response body won't be parsed",
              errorHandler.getClass().getName());
          errorResponse =
              ErrorResponse.builder()
                  .responseCode(response.getCode())
                  .withMessage(responseBody)
                  .build();
        }

      } catch (UncheckedIOException | IllegalArgumentException e) {
        // It's possible to receive a non-successful response that isn't a properly defined
        // ErrorResponse
        // without any bugs in the server implementation. So we ignore this exception and build an
        // error
        // response for the user.
        //
        // For example, the connection could time out before every reaching the server, in which
        // case we'll

View on GitHub (pinned to 86d9c8fc54)