apache/iceberg · error · UncheckedIOException

Failed to close HTTP client

Error message

Failed to close HTTP client

What it means

Thrown during RESTSessionCatalog.initialize when closing the temporary initialization RESTClient (or its init AuthSession) fails with an IOException. The config fetch itself succeeded, but the try-with-resources close of the bootstrap HTTP client failed, so initialization aborts with an UncheckedIOException.

Solutions

  1. Check network/proxy stability between client and REST server; retry catalog initialization.
  2. Inspect the wrapped IOException cause to see whether the server or an intermediary dropped the connection during close.
  3. Upgrade Iceberg — client close robustness improvements land regularly in the rest module.
  4. Verify server-side logs for errors on the /v1/config request lifecycle.

Example fix

// before: exception only says 'Failed to close HTTP client'
RESTCatalog catalog = new RESTCatalog();
catalog.initialize("prod", props); // retry on UncheckedIOException
// after: inspect cause and retry
try { catalog.initialize("prod", props); }
catch (UncheckedIOException e) { LOG.warn("init close failed", e.getCause()); /* retry with backoff */ }
Defensive patterns

Strategy: retry

Try / catch

try { catalog.initialize("name", props); } catch (UncheckedIOException e) { LOG.warn("init client close failed", e.getCause()); /* retry with backoff */ }

Prevention

When it happens

Trigger: RESTCatalog.initialize() / file IO catalog initialization where the try-with-resources block closing the initClient or initSession throws IOException — typically underlying connection teardown failures during close.

Common situations: Transient network issues while closing the bootstrap connection used to fetch /v1/config; proxies or load balancers that reset idle connections; flaky TLS termination during the init session close.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java:212

  @Override
  public void initialize(String name, Map<String, String> unresolved) {
    Preconditions.checkArgument(unresolved != null, "Invalid configuration: null");
    // resolve any configuration that is supplied by environment variables
    // note that this is only done for local config properties and not for properties from the
    // catalog service
    Map<String, String> props = EnvironmentUtil.resolveAll(unresolved);

    this.closeables = new CloseableGroup();

    this.authManager = AuthManagers.loadAuthManager(name, props);
    this.closeables.addCloseable(this.authManager);

    ConfigResponse config;
    try (RESTClient initClient = clientBuilder.apply(props);
        AuthSession initSession = authManager.initSession(initClient, props)) {
      config = fetchConfig(initClient.withAuthSession(initSession), initSession, props);
    } catch (IOException e) {
      throw new UncheckedIOException("Failed to close HTTP client", e);
    }

    // build the final configuration and set up the catalog's auth
    Map<String, String> mergedProps = config.merge(props);

    // Enable Idempotency-Key header for mutation endpoints if the server advertises support
    if (config.idempotencyKeyLifetime() != null) {
      this.mutationHeaders = RESTUtil::idempotencyHeaders;
    }

    if (config.endpoints().isEmpty()) {
      this.endpoints =
          PropertyUtil.propertyAsBoolean(
                  mergedProps,
                  RESTCatalogProperties.VIEW_ENDPOINTS_SUPPORTED,
                  RESTCatalogProperties.VIEW_ENDPOINTS_SUPPORTED_DEFAULT)
              ? ImmutableSet.<Endpoint>builder()
                  .addAll(DEFAULT_ENDPOINTS)

View on GitHub (pinned to 86d9c8fc54)