Skip to content

KeychainService fails to save OAuth token ( nullPointer exception ) #1300

@RafPe

Description

@RafPe

Looking for help on finding the root cause of not being able to run with custom IDP oauth clients on Tableau server.

Problem I am experiencing is that the whole flow of custom OAuth works as the server is able to retrieve the tokens from IDP ( Google ) but then it fails on KeyChainservice blowing up with one of checks being null and returning error 17 to the user

From a user perspective in the UI when trying to work with a workbook on the server it will just hang the UI.

I have this oauth clients configured with different classes ( but same label )

    <oauthConfigId>custom_athena_google</oauthConfigId>
    <!-- Config label added in 2023.2. Avoid if backwards compatibility is needed. -->
    <configLabel>Google</configLabel>

and

    <oauthConfigId>custom_redshift_google</oauthConfigId>
    <!-- Config label added in 2023.2. Avoid if backwards compatibility is needed. -->
    <configLabel>Google</configLabel>

I have spent countless hours looking through documentation and cannot find references to this particular issue.

The log references the error I found

2025-12-08 12:27:59.164 +0000 93882 (stgn,rafal.pieniazek@foobar.com,g*****d4) catalina-exec-1 vizportal: DEBUG com.tableausoftware.domain.keychain.KeychainService - Fetching keychain entry for class athena and instanceUrl null and role null
2025-12-08 12:27:59.164 +0000 93882 (stgn,rafal.pieniazek@foobar.com,g*****d4) catalina-exec-1 vizportal: INFO  com.tableausoftware.domain.keychain.KeychainService - event=KeychainService.addOAuthKeychainEntry.error totalTime=0.001 errorMessage=null
2025-12-08 12:27:59.164 +0000 93882 (stgn,rafal.pieniazek@foobar.com,g*****d4) catalina-exec-1 vizportal: ERROR com.tableausoftware.api.webclient.rest.WebClientRestService - Failed to add OAuth token
java.lang.NullPointerException: null
	at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:903) ~[guava-32.1.3-jre.jar:?]
	at com.tableausoftware.domain.keychain.jpa.KeychainEntryDaoJpa.find_aroundBody0(KeychainEntryDaoJpa.java:90) ~[tab-domain-keychain-latest.jar:?]
	at com.tableausoftware.domain.keychain.jpa.KeychainEntryDaoJpa$AjcClosure1.run(KeychainEntryDaoJpa.java:1) ~[tab-domain-keychain-latest.jar:?]
	at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:67) ~[spring-aspects-5.3.39.jar:5.3.39]
	at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:73) ~[spring-aspects-5.3.39.jar:5.3.39]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.39.jar:5.3.39]
	at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:71) ~[spring-aspects-5.3.39.jar:5.3.39]
	at com.tableausoftware.domain.keychain.jpa.KeychainEntryDaoJpa.find(KeychainEntryDaoJpa.java:88) ~[tab-domain-keychain-latest.jar:?]
	at com.tableausoftware.domain.keychain.KeychainService.addUserKeychainEntry_aroundBody80(KeychainService.java:2841) ~[tab-domain-keychain-latest.jar:?]
	at com.tableausoftware.domain.keychain.KeychainService$AjcClosure81.run(KeychainService.java:1) ~[tab-domain-keychain-latest.jar:?]
	at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:67) ~[spring-aspects-5.3.39.jar:5.3.39]
	at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:73) ~[spring-aspects-5.3.39.jar:5.3.39]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.39.jar:5.3.39]
	at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:71) ~[spring-aspects-5.3.39.jar:5.3.39]
	at com.tableausoftware.domain.keychain.KeychainService.addUserKeychainEntry(KeychainService.java:2782) ~[tab-domain-keychain-latest.jar:?]
	at com.tableausoftware.domain.keychain.KeychainService.persistKeyChainPair(KeychainService.java:505) ~[tab-domain-keychain-latest.jar:?]
	at com.tableausoftware.domain.keychain.KeychainService.addOAuthKeychainEntry(KeychainService.java:301) ~[tab-domain-keychain-latest.jar:?]
	at com.tableausoftware.domain.keychain.KeychainService.addOAuthKeychainEntry_aroundBody6(KeychainService.java:280) ~[tab-domain-keychain-latest.jar:?]
	at com.tableausoftware.domain.keychain.KeychainService$AjcClosure7.run(KeychainService.java:1) ~[tab-domain-keychain-latest.jar:?]
	at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:167) ~[aspectjrt-1.9.8.jar:?]
	at com.tableausoftware.utils.logging.StructuredLoggerAspect.runWithLogging(StructuredLoggerAspect.java:69) ~[structured-logging-20251.0.1.jar:?]
	at com.tableausoftware.domain.keychain.KeychainService.addOAuthKeychainEntry(KeychainService.java:280) ~[tab-domain-keychain-latest.jar:?]
	at com.tableausoftware.api.webclient.rest.WebClientRestService.addCredentialToOAuthKeychain(WebClientRestService.java:619) ~[tab-api-webclient-all-latest.jar:?]
	at com.tableausoftware.api.webclient.rest.WebClientRestService.addOAuthToken(WebClientRestService.java:562) ~[tab-api-webclient-all-latest.jar:?]
	at com.tableausoftware.api.webclient.rest.auth.AuthRestController.addOAuthToken_aroundBody2(AuthRestController.java:253) ~[tab-api-webclient-all-latest.jar:?]
	at com.tableausoftware.api.webclient.rest.auth.AuthRestController$AjcClosure3.run(AuthRestController.java:1) ~[tab-api-webclient-all-latest.jar:?]
	at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:167) ~[aspectjrt-1.9.8.jar:?]
	at com.tableausoftware.instrumentation.InstrumentedMethod.instrumentInvocation(InstrumentedMethod.java:97) ~[instrumentation-java-lib-20251.0.2.jar:?]
	at com.tableausoftware.instrumentation.InstrumentationAspect.aroundAnnotatedMethod(InstrumentationAspect.java:61) ~[instrumentation-java-lib-20251.0.2.jar:?]
	at com.tableausoftware.api.webclient.rest.auth.AuthRestController.addOAuthToken(AuthRestController.java:175) ~[tab-api-webclient-all-latest.jar:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:569) ~[?:?]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.39.jar:5.3.39]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.39.jar:5.3.39]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:903) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:809) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:529) ~[servlet-api.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.39.jar:5.3.39]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:623) ~[servlet-api.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:199) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[catalina.jar:9.0.105]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-websocket.jar:9.0.105]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[catalina.jar:9.0.105]
	at com.tableausoftware.endeavour.client.http.StandardInstrumentedFilter.doFilter(StandardInstrumentedFilter.java:47) ~[endeavour-java-4.10.0.jar:?]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[catalina.jar:9.0.105]
	at com.tableausoftware.web.utils.SafeRedirectFilter.doFilter(SafeRedirectFilter.java:69) ~[tab-web-utils-latest.jar:?]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[catalina.jar:9.0.105]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.39.jar:5.3.39]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.39.jar:5.3.39]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[catalina.jar:9.0.105]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) ~[catalina.jar:9.0.105]
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:656) ~[catalina.jar:9.0.105]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[catalina.jar:9.0.105]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[catalina.jar:9.0.105]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346) ~[catalina.jar:9.0.105]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) ~[tomcat-coyote.jar:9.0.105]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-coyote.jar:9.0.105]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935) ~[tomcat-coyote.jar:9.0.105]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1792) ~[tomcat-coyote.jar:9.0.105]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-coyote.jar:9.0.105]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189) ~[tomcat-util.jar:9.0.105]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658) ~[tomcat-util.jar:9.0.105]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-util.jar:9.0.105]
	at java.lang.Thread.run(Thread.java:840) ~[?:?]

Will appreciate any hints on what could be the possible solution here

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions