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
- Use an ErrorHandler (e.g. ErrorHandlers.defaultErrorHandler()) when configuring the HTTP client.
- Migrate custom Function-based handlers to extend/implement ErrorHandler and override parseResponse.
- Align client and catalog dependency versions so the same handler API is used.
- 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
- Always configure handlers that implement ErrorHandler
- Migrate off the legacy Function-based error mapper API
- Pin client/catalog versions consistently
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
- Unable to parse error response
- Unable to process (code: , type: )
- Cannot call commit on temporary table operations
- Cannot call refresh on temporary table operations
- Exception processing split
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'llView on GitHub (pinned to 86d9c8fc54)