[FCM] 푸시 발송 오류 원인 - Error getting access token for service account / Connection reset




증상

FCM Push 발송 시 아래와 같은 오류가 발생하면서 푸시발송이 정상적으로 되지 않았다.
(어쩔때는 정상적으로 되다가 안되다가 하는 증상)



원인

(나의 경우에는 코드에 문제가 없었지만)
회사의 네트워크에 보안설정에 의해 푸시 발송이 정상적으로 되지 않았다.
모바일 기기의 테더링으로 같은코드를 수행 시 정상적으로 푸시발송이 되는것을 확인 할 수 있었다.





com.google.firebase.messaging.FirebaseMessagingException: Unknown error while making a remote service call: Error getting access token for service account: java.net.SocketException: Connection reset

at com.google.firebase.messaging.FirebaseMessagingException.withMessagingErrorCode(FirebaseMessagingException.java:47)
at com.google.firebase.messaging.FirebaseMessagingClientImpl$MessagingErrorHandler.createException(FirebaseMessagingClientImpl.java:293)
at com.google.firebase.messaging.FirebaseMessagingClientImpl$MessagingErrorHandler.createException(FirebaseMessagingClientImpl.java:282)
at com.google.firebase.internal.AbstractHttpErrorHandler.handleIOException(AbstractHttpErrorHandler.java:63)
at com.google.firebase.internal.ErrorHandlingHttpClient.createHttpRequest(ErrorHandlingHttpClient.java:141)
at com.google.firebase.internal.ErrorHandlingHttpClient.send(ErrorHandlingHttpClient.java:92)
at com.google.firebase.internal.ErrorHandlingHttpClient.sendAndParse(ErrorHandlingHttpClient.java:72)
at com.google.firebase.messaging.FirebaseMessagingClientImpl.sendSingleRequest(FirebaseMessagingClientImpl.java:127)
at com.google.firebase.messaging.FirebaseMessagingClientImpl.send(FirebaseMessagingClientImpl.java:113)
at com.google.firebase.messaging.FirebaseMessaging$1.execute(FirebaseMessaging.java:135)
at com.google.firebase.messaging.FirebaseMessaging$1.execute(FirebaseMessaging.java:132)
at com.google.firebase.internal.CallableOperation.call(CallableOperation.java:36)
at com.google.firebase.messaging.FirebaseMessaging.send(FirebaseMessaging.java:102)
at com.google.firebase.messaging.FirebaseMessaging.send(FirebaseMessaging.java:86)
at kr.co._1004lucifer.util.FcmUtil.send(FcmUtil.java:47)
at kr.co._1004lucifer.util.FcmUtilTest.send(FcmUtilTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.io.IOException: Error getting access token for service account: java.net.SocketException: Connection reset
at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:444)
at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:157)
at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:145)
at com.google.auth.oauth2.ServiceAccountCredentials.getRequestMetadata(ServiceAccountCredentials.java:603)
at com.google.auth.http.HttpCredentialsAdapter.initialize(HttpCredentialsAdapter.java:91)
at com.google.firebase.internal.FirebaseRequestInitializer.initialize(FirebaseRequestInitializer.java:55)
at com.google.api.client.http.HttpRequestFactory.buildRequest(HttpRequestFactory.java:88)
at com.google.firebase.internal.HttpRequestInfo.newHttpRequest(HttpRequestInfo.java:105)
at com.google.firebase.internal.ErrorHandlingHttpClient.createHttpRequest(ErrorHandlingHttpClient.java:137)
... 39 more
Caused by: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
at sun.security.ssl.Alert.createSSLException(Alert.java:127)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:296)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:291)
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:141)
at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1279)
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1188)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:401)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:587)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1340)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1315)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:264)
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:113)
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:84)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1012)
at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:441)
... 47 more
Suppressed: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:83)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:384)
... 63 more
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:475)
at sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:469)
at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:159)
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:110)
... 60 more



댓글

  1. 혹시 어떤 방화벽 정책으로 해결하셧는지알수잇을가요? 현재 outbound에 대해서 80, 443, 5228, 5229, 5230 포트를 오픈으로 해놨는데 오류가 발생하며 전체 포트 오픈시에는 문제가 발생하지 않습니다.

    답글삭제
    답글
    1. 안녕하세요. 이제야 답변을 드리네요.
      위 글의 내용은 사내 개발망에서는 푸시가 발송되었다 안되었다 했었고, 테더링으로는 문제가 없는걸로 보아 사내 개발망 이슈로 보고 그냥 넘어갔었습니다.
      푸시는 서버에서 수행이 될테니까요..

      특정 포트를 오픈하거나 하지는 않았지만 문의주신걸 봤을 때는 발송하는 PC에서 네트워크 캡쳐를 통해 확인을 하시거나 인프라팀의 도움을 받아 네트워크 장비의 트래픽 확인을 요청하여 트러블슈팅을 할 수 있지 않을까 싶습니다.

      삭제

댓글 쓰기