ReactorClient is not refreshing the token, when response is 401
See original GitHub issueLooking at Operator.java
in cf-java-client source code, I see that in case of 401 responses, the reactor-client retries the requests with new token. So there should be no InvalidAccessToken
(401) thrown out of the library. But as you can see in the below stack trace, we are catching such exceptions, frequently, in our code.
cf-java-client v4.16.0
stack trace:
2022-01-28 00:49:57.294 DEBUG 36 --- [ry-client-nio-1] cloudfoundry-client.response : 401 /oauth/clients (16 ms)
2022-01-28 00:49:57.623 INFO 36 --- [undedElastic-20] s.c.s.c.ServiceInstanceBindingController : Deleting a service instance binding
2022-01-28 00:49:57.756 INFO 36 --- [ctor-http-nio-3] .s.WorkflowServiceInstanceBindingService : Deleting service instance binding
2022-01-28 00:49:57.761 DEBUG 36 --- [ry-client-nio-2] cloudfoundry-client.request : DELETE /oauth/clients/config-client-dfc1041e-5e88-45d4-8311-2ab87b2620f1
2022-01-28 00:49:57.776 ERROR 36 --- [ry-client-nio-2] .s.WorkflowServiceInstanceBindingService : Error deleting service instance binding. error=invalid_token: Invalid access token: expired at Thu Jan 27 17:49:54 UTC 2022
org.cloudfoundry.uaa.UaaException: invalid_token: Invalid access token: expired at Thu Jan 27 17:49:54 UTC 2022
at org.cloudfoundry.reactor.util.ErrorPayloadMappers.lambda$null$8(ErrorPayloadMappers.java:89) ~[cloudfoundry-client-reactor-4.16.0.RELEASE.jar!/:na]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Assembly trace from producer [reactor.core.publisher.MonoFlatMap] :
reactor.core.publisher.Mono.checkpoint(Mono.java:1884)
org.cloudfoundry.reactor.uaa.clients.ReactorClients.delete(ReactorClients.java:111)
Error has been observed at the following site(s):
|_ Mono.checkpoint ⇢ at org.cloudfoundry.reactor.uaa.clients.ReactorClients.delete(ReactorClients.java:111)
Stack trace:
at org.cloudfoundry.reactor.util.ErrorPayloadMappers.lambda$null$8(ErrorPayloadMappers.java:89) ~[cloudfoundry-client-reactor-4.16.0.RELEASE.jar!/:na]
at org.cloudfoundry.reactor.util.ErrorPayloadMappers.lambda$null$11(ErrorPayloadMappers.java:112) ~[cloudfoundry-client-reactor-4.16.0.RELEASE.jar!/:na]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:112) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:213) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:123) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:178) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:96) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1812) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onComplete(FluxDoFinally.java:138) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.16.RELEASE.jar!/:3.3.16.RELEASE]
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:383) ~[reactor-netty-0.9.19.RELEASE.jar!/:0.9.19.RELEASE]
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:373) ~[reactor-netty-0.9.19.RELEASE.jar!/:0.9.19.RELEASE]
at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:429) ~[reactor-netty-0.9.19.RELEASE.jar!/:0.9.19.RELEASE]
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:655) ~[reactor-netty-0.9.19.RELEASE.jar!/:0.9.19.RELEASE]
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:96) ~[reactor-netty-0.9.19.RELEASE.jar!/:0.9.19.RELEASE]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[netty-codec-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) ~[netty-codec-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296) ~[netty-codec-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:271) ~[netty-handler-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1504) ~[netty-handler-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1253) ~[netty-handler-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1300) ~[netty-handler-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508) ~[netty-codec-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447) ~[netty-codec-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.63.Final.jar!/:4.1.63.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.63.Final.jar!/:4.1.63.Final]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_222]
Issue Analytics
- State:
- Created 2 years ago
- Comments:14 (5 by maintainers)
Top Results From Across the Web
Angular2: Catching 401 error for token refresh - Stack Overflow
I'm new to Angular2 and trying catch 401 error for token refresh with the plan to retry original request... Here is my authService.refresh...
Read more >OidcClientFilter produces periodic 401 errors when token ...
OidcClientFilter should refresh the Token before it expires. Actual behavior. We are getting periodic 401 errors which can also not be ...
Read more >'401 Unauthorized HTTP' for REST API token that expires in ...
If you attempt to use an expired token, you'll receive a "401 Unauthorized HTTP" response. When this happens, you'll need to refresh the...
Read more >Can you confirm that we need to always refresh the OAuth ...
Can you confirm that we need to always refresh the OAuth token whenever we receive a `401 Unauthorized` response back from the QBO...
Read more >Servicenow Oauth token API giving 401 access denie...
This API is used in order to refresh the access_token every time. ... can I get 401 unauthorised and on next call I...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@pivotal-david-osullivan, The only way i could reproduce the issue in my local env. was by providing different reason message for 401 status code from the mock UAA server. So if the UAA server returns anything other than
Unauthorized
reason message for 401 code, the current cf-java-client fails to compare it properly.The code you’ve merged fixes this issue. But I don’t have any way to verify if UAA has ever returned a 401 code with a custom reason message in our production env.
Oh, ok. Good to know. I thought users could do that. Thanks