{"record":{"id":"c6464c0010b6b645","repo":"apache/iceberg","slug":"unknown-error-handler-response-body-won-t-be-p","errorCode":null,"errorMessage":"Unknown error handler {}, response body won't be parsed","messagePattern":"Unknown error handler (.+?), response body won't be parsed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/rest/HTTPClient.java","lineNumber":214,"sourceCode":"        .responseCode(response.getCode())\n        .withMessage(message)\n        .withType(type)\n        .build();\n  }\n\n  // Process a failed response through the provided errorHandler, and throw a RESTException if the\n  // provided error handler doesn't already throw.\n  private static void throwFailure(\n      ClassicHttpResponse response, String responseBody, Consumer<ErrorResponse> errorHandler) {\n    ErrorResponse errorResponse = null;\n\n    if (responseBody != null) {\n      try {\n        if (errorHandler instanceof ErrorHandler) {\n          errorResponse =\n              ((ErrorHandler) errorHandler).parseResponse(response.getCode(), responseBody);\n        } else {\n          LOG.warn(\n              \"Unknown error handler {}, response body won't be parsed\",\n              errorHandler.getClass().getName());\n          errorResponse =\n              ErrorResponse.builder()\n                  .responseCode(response.getCode())\n                  .withMessage(responseBody)\n                  .build();\n        }\n\n      } catch (UncheckedIOException | IllegalArgumentException e) {\n        // It's possible to receive a non-successful response that isn't a properly defined\n        // ErrorResponse\n        // without any bugs in the server implementation. So we ignore this exception and build an\n        // error\n        // response for the user.\n        //\n        // For example, the connection could time out before every reaching the server, in which\n        // case we'll","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/HTTPClient.java#L196-L232","documentation":"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.","triggerScenarios":"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.","commonSituations":"Code written against the older REST client API, custom client builders injecting their own handler type, mixing client versions where the handler interface changed.","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."],"exampleFix":"// before\nHTTPClient.builder().withErrorMapper(code -> \"HTTP \" + code).build();\n// after\nHTTPClient.builder().withErrorHandler(ErrorHandlers.defaultErrorHandler()).build();","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"if (!(handler instanceof ErrorHandler)) { handler = ErrorHandlers.defaultErrorHandler(); }","tryCatchPattern":"try { restClient.post(path, body, ErrorHandler.class.cast(handler)); } catch (RESTException e) { /* fallback ErrorResponse still carries status + raw body */ }","preventionTips":["Always configure handlers that implement ErrorHandler","Migrate off the legacy Function-based error mapper API","Pin client/catalog versions consistently"],"tags":["rest","http","error-handling","api-migration"],"backgroundTag":"unexpected-response-shape","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}