Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 1 month ago by QuasarAstronaut159

How can I resolve io.netty.channel.StacklessClosedChannelException when downloading a blob from an Azure SAS URL using Java?

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

I am generating a ByteStream from an Azure Storage SAS URL using the code below, but I get an io.netty.channel.StacklessClosedChannelException when downloading the blob. My SAS URL is valid, and I suspect the issue may be due to a versioning bug on Windows (see reference: Click here).

JAVA
ConnectionProvider connectionProvider = ConnectionProvider.builder("custom-connection-provider") .maxConnections(200) .pendingAcquireMaxCount(5000) .build(); BlobClient blobClient = new BlobClientBuilder() .endpoint(searchMultipleWrapper.getSasUrl().trim()) // IT IS MY VALID SAS URL .httpClient(new NettyAsyncHttpClientBuilder() .connectionProvider(connectionProvider) .readTimeout(Duration.ofMinutes(10)) .writeTimeout(Duration.ofMinutes(10)) .responseTimeout(Duration.ofMinutes(10)) .build()) .retryOptions(new RequestRetryOptions( RetryPolicyType.EXPONENTIAL, 5, 2, null, null, null )) .buildClient(); log.info("BlobClient Object check {} ", blobClient); // Use try-with-resources to ensure InputStream is closed try (InputStream inputStream = blobClient.openInputStream(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { // Transfer data from InputStream to ByteArrayOutputStream inputStream.transferTo(byteArrayOutputStream); // Convert to Base64 byte[] imageBytes = byteArrayOutputStream.toByteArray(); String base64Image = Base64.getEncoder().encodeToString(imageBytes); log.info("Base 64 : {} ", base64Image); // Log the Base64 string (truncated for safety) log.info("Base64 Image (truncated): " + base64Image.substring(0, Math.min(base64Image.length(), 100)) + "..."); } catch (Exception e) { log.error("Error while processing blob content", e); }

Below is the exception stack trace I am receiving:

stack_trace":"reactor.core.Exceptions$ReactiveException:
io.netty.channel.StacklessClosedChannelException
at

Heading ##reactor.core.Exceptions.propagate(Exceptions.java:410)
at


reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:102)
at
reactor.core.publisher.Mono.block(Mono.java:1779)
at
com.azure.storage.blob.specialized.BlobClientBase.openInputStream(BlobClientBase.java:393)
at
com.azure.storage.blob.specialized.BlobClientBase.openInputStream(BlobClientBase.java:323)
at
com.azure.storage.blob.specialized.BlobClientBase.openInputStream(BlobClientBase.java:312)
at
com.azure.storage.blob.specialized.BlobClientBase.openInputStream(BlobClientBase.java:299)

Please help me troubleshoot and resolve this issue.

0

Comments 0

Answers 3

Views 191

3 Answers

Answer by StackOverflowTychoAI Agent 1 month ago

0

Below is a list of suggestions to help troubleshoot and fix the issue you're experiencing with the StacklessClosedChannelException when reading the blob:

1. Upgrade Dependencies

The error you referenced (see GitHub issue #40106) is known to be present in certain versions of the Azure Storage Blob SDK when used on Windows with the Netty HTTP client. You should:

  • Ensure you are using the latest version of the Azure Storage Blob SDK. The issue may have been fixed in a later release.
  • Also update the Netty dependencies (if applicable) to versions known to work with your sdk; version mismatches can sometimes cause channel issues.

2. Consider Using an Alternate HTTP Client

Since the problem seems to be related to the Netty HTTP client configuration on Windows, you might try switching to another supported HTTP client (such as the OkHttp client provided by Azure) to see if that resolves the issue. For example:

JAVA
BlobClient blobClient = new BlobClientBuilder() .endpoint(searchMultipleWrapper.getSasUrl().trim()) .httpClient(new OkHttpAsyncHttpClientBuilder() .readTimeout(Duration.ofMinutes(10)) .writeTimeout(Duration.ofMinutes(10)) .responseTimeout(Duration.ofMinutes(10)) .build()) .retryOptions(new RequestRetryOptions( RetryPolicyType.EXPONENTIAL, 5, 2, null, null, null)) .buildClient();

Switching to a different HTTP client can be a quick way to determine if the Netty-specific issue is the root cause.

3. Validate SAS URL and Timeouts

  • SAS URL Validity: Double-check that there are no trailing spaces or encoding issues with your SAS URL.
  • Timeouts: The long read and write timeouts (10 minutes) are configured, which may interact with network conditions. Although likely unrelated, you could experiment with shorter timeouts to see if it changes the behavior.

4. Review Connection Provider Settings

Ensure that the custom connection provider configuration isn’t affecting the network connection negatively. You have configured a high number of max connections and a large pending acquire count. It might be worth testing with default settings to rule out throttling issues.

Summary

Considering that the exception is related to the Netty HTTP pipeline closing a channel unexpectedly, and you've already identified a similar reported bug, the most promising approaches are:

  • Upgrading to the latest versions of the Azure Storage Blob SDK and Netty libraries.
  • Testing with an alternative HTTP client (like OkHttp) to determine if the Netty implementation is causing the problem on Windows.

By taking these steps, you should be able to isolate and resolve the issue with the ByteStream generation from the SAS URL.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Answer by InterstellarRanger201 1 month ago

0

generating the ByteStream from the SasUrl of Azure storage

You can use the below code with proper version and with sas url to generate the ByteStream using Azure Java SDK.

Code:

JAVA
import com.azure.core.http.netty.NettyAsyncHttpClientBuilder; import com.azure.storage.blob.BlobClient; import com.azure.storage.blob.BlobClientBuilder; import com.azure.storage.common.policy.RequestRetryOptions; import com.azure.storage.common.policy.RetryPolicyType; import reactor.netty.resources.ConnectionProvider; import java.io.ByteArrayOutputStream; import java.time.Duration; import java.util.Base64; public class App { public static void main(String[] args) { // Example SAS URL (replace with your actual SAS URL) String sasUrl = "https://<Account name>.blob.core.windows.net/<Conatiner name>/<blob name>?sp=r&st=2025-01-24T03:07:42Z&se=2025-01-24T11:07:42Z&spr=https&sv=2022-11-02&sr=b&sig=redacted"; ConnectionProvider connectionProvider = ConnectionProvider.builder("custom-connection-provider") .maxConnections(200) // Adjust as per your concurrency needs .pendingAcquireMaxCount(5000) .build(); BlobClient blobClient = new BlobClientBuilder() .endpoint(sasUrl.trim()) .retryOptions(new RequestRetryOptions( RetryPolicyType.EXPONENTIAL, 5, 2, null, null, null )) .httpClient(new NettyAsyncHttpClientBuilder() .connectionProvider(connectionProvider) .readTimeout(Duration.ofMinutes(10)) .writeTimeout(Duration.ofMinutes(10)) .responseTimeout(Duration.ofMinutes(10)) .build()) .buildClient(); System.out.println("BlobClient created successfully"); // Read blob content as a Base64-encoded string try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { // Download blob content into the output stream blobClient.downloadStream(byteArrayOutputStream); // Convert the downloaded bytes to Base64 byte[] imageBytes = byteArrayOutputStream.toByteArray(); String base64Image = Base64.getEncoder().encodeToString(imageBytes); // Log the Base64 string (truncated for safety) System.out.println("Base64 Image (truncated): " + base64Image.substring(0, Math.min(base64Image.length(), 100)) + "..."); } catch (Exception e) { System.err.println("Error while processing blob content"); e.printStackTrace(); } } }

My versions are azure-storage-blob is 12.29.0 and azure-core-http-netty is 1.15.7.

Output:

BASH
BlobClient created successfully Base64 Image (truncated): /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAxxxxxxxxxxxxxxHBwcGBwcICQsJCAgKCAcHCg0KCgsM...

enter image description here

Reference:
Download a blob with Java - Azure Storage | Microsoft Learn

No comments yet.

Answer by AstroObserver391 1 month ago

0

As I have mentioned in the question that it might be an open issue from the dependency side

I have used the below dependency which works perfectly previously I was using the azure-storage-blob artifactId which was casing the above-mentioned issue.

XML
<dependency> <groupId>com.azure</groupId> <artifactId>azure-core-http-okhttp</artifactId> <version>1.12.0</version> </dependency>

No comments yet.

Discussion

No comments yet.