apache/iceberg · warning

Failed to close S3SeekableInputStreamFactory

Error message

Failed to close S3SeekableInputStreamFactory

What it means

A warning from AnalyticsAcceleratorUtil's static STREAM_FACTORY_CACHE cleanup: closing the cached S3SeekableInputStreamFactory threw an IOException. The factory (used by the S3 Analytics Accelerator for seekable reads) could not release its resources cleanly; the warning is logged and close proceeds silently otherwise.

Source

Thrown at aws/src/main/java/org/apache/iceberg/aws/s3/AnalyticsAcceleratorUtil.java:91

  private static S3SeekableInputStreamFactory createNewFactory(
      Pair<S3AsyncClient, S3FileIOProperties> cacheKey) {
    ConnectorConfiguration connectorConfiguration =
        new ConnectorConfiguration(cacheKey.second().s3AnalyticsacceleratorProperties());
    S3SeekableInputStreamConfiguration streamConfiguration =
        S3SeekableInputStreamConfiguration.fromConfiguration(connectorConfiguration);
    ObjectClientConfiguration objectClientConfiguration =
        ObjectClientConfiguration.fromConfiguration(connectorConfiguration);

    ObjectClient objectClient = new S3SdkObjectClient(cacheKey.first(), objectClientConfiguration);
    return new S3SeekableInputStreamFactory(objectClient, streamConfiguration);
  }

  private static void close(S3SeekableInputStreamFactory factory) {
    if (factory != null) {
      try {
        factory.close();
      } catch (IOException e) {
        LOG.warn("Failed to close S3SeekableInputStreamFactory", e);
      }
    }
  }

  public static void cleanupCache(
      S3AsyncClient asyncClient, S3FileIOProperties s3FileIOProperties) {
    STREAM_FACTORY_CACHE.invalidate(Pair.of(asyncClient, s3FileIOProperties));
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check the logged IOException cause; if it's the async client shutdown, ensure the S3AsyncClient passed to cleanupCache outlives the factory
  2. Call AnalyticsAcceleratorUtil.cleanupCache explicitly during application shutdown to close factories in a controlled state
  3. Avoid reusing a factory after its close attempt; re-acquire via the cache
  4. If repeated, disable the analytics-accelerator feature via S3FileIOProperties if you don't need it

Example fix

// before
S3AsyncClient client = S3AsyncClient.create();
client.close(); // closed before factory cleanup -> factory.close() throws
AnalyticsAcceleratorUtil.cleanupCache(client, props);
// after
S3AsyncClient client = S3AsyncClient.create();
AnalyticsAcceleratorUtil.cleanupCache(client, props); // close factory first
client.close();
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the client passed to cleanupCache is still open
if (!asyncClientIsShutdown) {
  AnalyticsAcceleratorUtil.cleanupCache(asyncClient, s3FileIOProperties);
}

Type guard

boolean factoryClosable = factory != null; // mirror the util's null guard

Prevention

When it happens

Trigger: Cleanup cache eviction (STREAM_FACTORY_CACHE removal callback) or explicit cleanupCache() invoking factory.close() while the factory's underlying resources (clients, buffers) are in a bad state, e.g. already partially closed or its async client failing shutdown.

Common situations: JVM shutdown with the cache still holding factories; swapping S3FileIOProperties (region/endpoint changes) causing cache eviction; closing a factory whose underlying S3AsyncClient was already shut down by user code.

Related errors


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