Skip to content

Netty version difference between Azure SDK and Spring Boot #48126

Description

We would like to hear from MSFT team on this Netty Version difference between multiple BOMs ..

Spring Boot Netty Version Azure Spring Azure SDK Azure Netty Version
4.0.0 4.2.7.Final 7.0.0 1.16.3 4.1.130.Final

This results confused log message ( as Azure SDK and Netty are transitive dependencies)

The following Netty versions were found on the classpath and have a mismatch with the versions used by azure-core-http-netty. If your application runs without issue this message can be ignored, otherwise please align the Netty versions used in your application. For more information, see https://aka.ms/azsdk/java/dependency/troubleshoot.

Though we understand Azure SDK is completely different than other Frameworks (Spring Boot, Azure Cloud), is there way to resolve this version difference ?

  1. Adhere to latest version along with other frameworks (Spring Boot) (preferred)
  2. Is there any possibility to suppress this log?

Being owners of Azure SDK and Azure Cloud, how would like to resolve this ?

Activity

  1. added
    customer-reportedIssues that are reported by GitHub users external to the Azure organization.
    needs-triageWorkflow: This is a new issue that needs to be triaged to the appropriate team.
    questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that
    on Feb 26, 2026
  2. anumalasri commented on Feb 27, 2026

    @anumalasri
    Author

    Spring Boot v4 supports both Jackson3 and Jackson2.

    Within Jackson2, the version of 2.18.x from azure and 2.20.x from Spring Bot

    Image

    Warning Log from c.a.c.i.Utils class : Neither Afterburner nor Blackbird Jackson module loaded. Consider adding one to your classpath for maximum Jackson performance.

  3. added
    bugThis issue requires a change to an existing behavior in the product in order to be resolved.
    and removed
    questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that
    needs-triageWorkflow: This is a new issue that needs to be triaged to the appropriate team.
    on Mar 3, 2026
  4. anumalasri commented on Mar 10, 2026

    @anumalasri
    Author

    Sameeksha Vaity (@samvaity) Alan Zimmer (@alzimmermsft) Could you please share your comments on this issue ?

  5. alzimmermsft commented on Mar 10, 2026

    @alzimmermsft
    Member

    Adhere to latest version along with other frameworks (Spring Boot) (preferred)

    At least for Jackson dependencies, the Azure SDKs should be fairly resilient to minor version skew in resolved dependencies, so we're unlikely to upgrade soonish but the logs can be ignored about them. The Netty minor dependency change though was found to have upgrade bugs found in this PR: #47563, and likely won't be upgraded for a while as the root issues are in JDK <-> Netty interactions that could cause crashes in an application.

    Since we support multiple versions of Spring (5.x, 6.x, 7.x, etc) at a time we generally try to use the lowest matching versions when possible. Right now, we're in a bit of a difficult spot as there are API breaking changes between the versions they use where if we upgrade we can break 5.x support but by not upgrading we can break 7.x support.

    Is there any possibility to suppress this log?

    For the Netty log, you should be able to disable logs from com.azure.core.http.netty.implementation.NettyUtility (logs the message in the original issue description, and is the only log message produced by that class: https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/core/azure-core-http-netty/src/main/java/com/azure/core/http/netty/implementation/NettyUtility.java#L98).

    For the Jackson log, you should be able to disable logs from com.azure.core.implementation.jackson.JacksonVersion (one of the possible logs about Jackson, https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/core/azure-core/src/main/java/com/azure/core/implementation/jackson/JacksonVersion.java).

    Kushagra Thapar (@kushagraThapar), for the log messages about Blackbird and Afterburner (https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/Utils.java#L158), we may want to drop the log level down to INFO or VERBOSE as it's an optional import to improve performance.

  6. jbauerrfid commented on Mar 17, 2026

    @jbauerrfid

    In Spring Boot it is possible to select a different version of netty by adding to the pom.xml of the current project:

    	<properties>
    		<netty.version>4.1.130.Final</netty.version>
    	</properties>

    But in Azure SDK Microsoft forces a specific version of netty.io on top of us, and they don't support a maven property to override the version.

    They ignore the fact that the root of the project dependencies usually comes from Spring Initializer, and then developers add dependencies from Azure SDK where they need functionality not supported by Spring out of the box. Instead they pretend they own Spring Boot and are the source of truth of all dependency versions.

    The Azure SDK should get more flexibility to let developers chose which common dependencies should be used. Also the Microsoft Spring Boot starter is no valid alternative as it causes trouble with other items from the original Spring framework.

  7. anumalasri commented on Mar 18, 2026

    @anumalasri
    Author

    At least for Jackson dependencies, the Azure SDKs should be fairly resilient to minor version skew in resolved dependencies, so we're unlikely to upgrade soonish but the logs can be ignored about them. The Netty minor dependency change though was found to have upgrade bugs found in this PR: #47563, and likely won't be upgraded for a while as the root issues are in JDK <-> Netty interactions that could cause crashes in an application.

    Are you saying Azure SDK is NOT compatible with Netty 4.2.x version ?

    Since we support multiple versions of Spring (5.x, 6.x, 7.x, etc) at a time we generally try to use the lowest matching versions when possible. Right now, we're in a bit of a difficult spot as there are API breaking changes between the versions they use where if we upgrade we can break 5.x support but by not upgrading we can break 7.x support.

    Spring Major versions can bring different versions of dependencies and required to manage compatible versions for Major version. Shall we Azure Spring Cloud to support these versions accordingly?

  8. alzimmermsft commented on Mar 19, 2026

    @alzimmermsft
    Member

    Are you saying Azure SDK is NOT compatible with Netty 4.2.x version ?

    API usage-wise, everything works fine, but Netty 4.2 has some runtime changes that caused issues when using default settings on Java 25 (a Java 25 bug), this issue goes into more details: netty/netty#16071

    Due to that bug, we're holding off on upgrading to Netty 4.2 as we use AsynchronousFileChannel in frequently used code paths and don't want to set any configuration settings for Netty from the SDK. So, we could upgrade, but it would require all SDK users to possibly need to set Netty configurations to work around that bug.

  9. 3 remaining items

  10. anumalasri commented on May 11, 2026

    @anumalasri
    Author

    netty/netty#16071 has closed.

    Netty has released patch versions 4.1.133, 4.2.13, fixing High CVEs.

    Can we able to get details on how MSFT going to manage Netty version in their modules ?

    Please note that Spring Boot has almost ready to release v4.1.0 on May 21, 2026.

  11. EugenMayer commented on May 12, 2026

    @EugenMayer

    using the graph client in Spring boot right now is impossible due to azure compiling against netty 4.1 and SB4.2 uses netty 4.2 (for good reasons

    This leads to

    java.lang.UnsatisfiedLinkError: 'boolean io.netty.internal.tcnative.SSL.setCurvesList0(long, java.lang.String)'
    	at io.netty.internal.tcnative.SSL.setCurvesList0(Native Method)
    	at io.netty.internal.tcnative.SSL.setCurvesList(SSL.java:588)
    	at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.setSSLParameters(ReferenceCountedOpenSslEngine.java:2255)
    	at reactor.netty.http.client.HttpClientSecurityUtils.lambda$static$0(HttpClientSecurityUtils.java:39)
    	at reactor.netty.tcp.SslProvider.configure(SslProvider.java:429)
    	at reactor.netty.tcp.SslProvider.addSslHandler(SslProvider.java:459)
    	at reactor.netty.http.client.HttpClientConfig$HttpClientChannelInitializer.onChannelInit(HttpClientConfig.java:1185)
    	at reactor.netty.transport.TransportConfig$TransportChannelInitializer.initChannel(TransportConfig.java:423)
    	at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:128)
    	at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:111)
    	at io.netty.channel.AbstractChannelHandlerContext.callHandlerAdded(AbstractChannelHandlerContext.java:989)
    	at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:558)
    	at io.netty.channel.DefaultChannelPipeline.internalAdd(DefaultChannelPipeline.java:203)
    	at io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:209)
    	at io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:307)
    	at io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:288)
    	at reactor.netty.resources.DefaultPooledConnectionProvider$PooledConnectionAllocator$PooledConnectionInitializer.initChannel(DefaultPooledConnectionProvider.java:598)
    	at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:128)
    	at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:111)
    	at io.netty.channel.AbstractChannelHandlerContext.callHandlerAdded(AbstractChannelHandlerContext.java:989)
    	at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:558)
    	at io.netty.channel.DefaultChannelPipeline.access$100(DefaultChannelPipeline.java:45)
    	at io.netty.channel.DefaultChannelPipeline$PendingHandlerAddedTask.execute(DefaultChannelPipeline.java:1482)
    	at io.netty.channel.DefaultChannelPipeline.callHandlerAddedForAllHandlers(DefaultChannelPipeline.java:1136)
    	at io.netty.channel.DefaultChannelPipeline.invokeHandlerAddedIfNeeded(DefaultChannelPipeline.java:599)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe.lambda$register0$0(AbstractChannel.java:381)
    	at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:604)
    	at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:571)
    	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:506)
    	at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:650)
    	at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:639)
    	at io.netty.util.concurrent.DefaultPromise.setSuccess(DefaultPromise.java:111)
    	at io.netty.channel.DefaultChannelPromise.setSuccess(DefaultChannelPromise.java:78)
    	at io.netty.channel.DefaultChannelPromise.setSuccess(DefaultChannelPromise.java:73)
    	at io.netty.channel.epoll.AbstractEpollChannel.lambda$doRegister$0(AbstractEpollChannel.java:306)
    	at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:604)
    	at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:571)
    	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:506)
    	at io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:199)
    	at io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:37)
    	at io.netty.channel.epoll.AbstractEpollChannel.doRegister(AbstractEpollChannel.java:299)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:405)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe.access$300(AbstractChannel.java:288)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:352)
    	at io.netty.util.concurrent.AbstractEventExecutor.runTask$$$capture(AbstractEventExecutor.java:148)
    	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java)
    	at --- Async.Stack.Trace --- (captured by IntelliJ IDEA debugger)
    	at io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java)
    	at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:1027)
    	at io.netty.util.concurrent.SingleThreadEventExecutor.execute0(SingleThreadEventExecutor.java:993)
    	at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:983)
    	at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:349)
    	at reactor.netty.transport.TransportConnector.doInitAndRegister(TransportConnector.java:295)
    	at reactor.netty.transport.TransportConnector.connect(TransportConnector.java:166)
    	at reactor.netty.transport.TransportConnector.connect(TransportConnector.java:125)
    	at reactor.netty.resources.DefaultPooledConnectionProvider$PooledConnectionAllocator.lambda$connectChannel$0(DefaultPooledConnectionProvider.java:559)
    	at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:61)
    	at reactor.core.publisher.Mono.subscribe(Mono.java:4512)
    	at reactor.core.publisher.Mono.subscribeWith(Mono.java:4578)
    	at reactor.core.publisher.Mono.subscribe(Mono.java:4478)
    	at reactor.core.publisher.Mono.subscribe(Mono.java:4414)
    	at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:450)
    	at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:629)
    	at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:307)
    	at reactor.netty.internal.shaded.reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:440)
    	at reactor.netty.resources.DefaultPooledConnectionProvider$DisposableAcquire.onSubscribe(DefaultPooledConnectionProvider.java:226)
    	at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:746)
    	at reactor.netty.resources.PooledConnectionProvider.lambda$acquire$3(PooledConnectionProvider.java:207)
    	at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:61)
    	at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.lambda$subscribe$0(HttpClientConnect.java:298)
    	at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:61)
    	at reactor.core.publisher.FluxRetryWhen.subscribe(FluxRetryWhen.java:80)
    	at reactor.core.publisher.MonoRetryWhen.subscribeOrReturn(MonoRetryWhen.java:46)
    	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:63)
    	at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.subscribe(HttpClientConnect.java:301)
    	at reactor.core.publisher.Mono.subscribe(Mono.java:4512)
    	at reactor.core.publisher.Mono.block(Mono.java:1727)
    	at com.azure.core.http.netty.NettyAsyncHttpClient.sendSync(NettyAsyncHttpClient.java:194)
    

    So this one is more than 'only' a 'high CVE' -its no a blocker generally

  12. changed the title [-]Netty version difference between Azure Cloud and Spring Boot[/-] [+]Netty version difference between Azure SDK and Spring Boot[/+] on May 13, 2026
  13. EugenMayer commented on May 19, 2026

    @EugenMayer

    Another 10 CVEs for netty 4.1 today. Could we please get this ticket moving (migrating to netty 4.2). This would solve both, the open CVEs and also the SpringBoot 4 compatiblity

  14. EugenMayer commented on May 19, 2026

    @EugenMayer

    Related issues:

    Kind of related (since it can replace the netty dependency)

    Just to be clear, the netty version difference does not only block spring boot 4.1 GA - it does block the entire spring boot 4.x migration.

    Any other readers, are there any alternatives to this client? We are only consuming the GraphAPI to read users/groups and are not going to block our entire Spring Boot migration because of this library. It just does not seem there is any movement at all in this regard so it might be legitimate to ask for alterntive client - or just implement an client while using the types at https://mvnrepository.com/artifact/com.azure/azure-core - authentication could be a little more effort though.

  15. slandelle commented on Sep 10, 2026

    @slandelle

    Eugen Mayer (@EugenMayer) Your problem is probably just a version mismatch between some netty modules.
    You should check your dependency tree and verify that all main netty modules have the same version and that it's compatible with the version of the netty-tcnative modules.

    For example, the latest netty version 4.2.18.Final is supposed to work with io.netty:netty-tcnative 2.0.84.Final. Any other combination is not supported and might break.

    See https://central.sonatype.com/artifact/io.netty/netty-bom/4.2.18.Final/overview:

    <tcnative.version>2.0.84.Final</tcnative.version>

    Note: You should consider using this BOM in your build so you can enforce all netty modules versions.

  16. EugenMayer commented on Sep 10, 2026

    @EugenMayer

    Stephane Landelle (@slandelle) thanks for the hints and the follow up.

    We removed this library from our software due to this very issue and others mentioned here. At some point, waiting is just no longer a viable option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugThis issue requires a change to an existing behavior in the product in order to be resolved.customer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK team

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions