ECONNREFUSED Error when accessing Astro server api endpoint

dannyhousefolios
PRO

6 months ago

I have deployed an Astro app which has server api endpoints. Calling the api endpoint in a server rendered page fails with this error:
http://client-survey-app.railway.internal:80

Jan 03 16:49:51

error TypeError: fetch failed

Jan 03 16:49:51

at node:internal/deps/undici/undici:12618:11

Jan 03 16:49:51

at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Jan 03 16:49:51

at async file:///app/dist/server/pages/surveys/_survey_.astro.mjs:16:22

Jan 03 16:49:51

at async callComponentAsTemplateResultOrResponse (file:///app/dist/server/chunks/astro/server_BEPnXAtQ.mjs:1474:25)

Jan 03 16:49:51

at async renderToAsyncIterable (file:///app/dist/server/chunks/astro/server_BEPnXAtQ.mjs:1516:26)

Jan 03 16:49:51

at async renderPage (file:///app/dist/server/chunks/astro/server_BEPnXAtQ.mjs:2353:24)

Jan 03 16:49:51

at async lastNext (file:///app/dist/server/chunks/_@astrojs-ssr-adapter_SUSfxLNh.mjs:2667:25)

Jan 03 16:49:51

at async callMiddleware (file:///app/dist/server/chunks/_@astrojs-ssr-adapter_SUSfxLNh.mjs:816:10)

Jan 03 16:49:51

at async RenderContext.render (file:///app/dist/server/chunks/_@astrojs-ssr-adapter_SUSfxLNh.mjs:2698:22)

Jan 03 16:49:51

at async NodeApp.render (file:///app/dist/server/chunks/_@astrojs-ssr-adapter_SUSfxLNh.mjs:3344:18) {

Jan 03 16:49:51

cause: Error: connect ECONNREFUSED fd12:bf0f:d489::22:93b0:1161:80

Jan 03 16:49:51

at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)

Jan 03 16:49:51

at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:128:17) {

Jan 03 16:49:51

errno: -111,

Jan 03 16:49:51

code: 'ECONNREFUSED',

Jan 03 16:49:51

syscall: 'connect',

Jan 03 16:49:51

address: 'fd12:bf0f:d489::22:93b0:1161',

Jan 03 16:49:51

port: 80

Jan 03 16:49:51

}

Jan 03 16:49:51

}

Initially, I used the railway recommended astro config setting:
... server: { host: '0.0.0.0' },

But it failed. I added a port number and used both the internal and public service urls at a time with the specified port numbers but they still failed.
However, when I run the astro build and preview commands in a local environment, it works just fine

Solved

6 Replies

chandrika
EMPLOYEE

6 months ago

Hi Danny! Have a few suggestions for ya:

1) Could you please check out our Astro deployment guide https://docs.railway.com/guides/astro ?

2) This could be a CORs issue - this looks like a similar issue as yours (works locally but not on the server) https://stackoverflow.com/questions/49343024/getting-typeerror-failed-to-fetch-when-the-request-hasnt-actually-failed — could you please see if updating the Access-Control-Allow-Origin in the response headers helps? There's a detailed guide within the comments of the accepted answer as well https://medium.com/@baphemot/understanding-cors-18ad6b478e2b


Status changed to Awaiting User Response railway[bot] 6 months ago


dannyhousefolios
PRO

6 months ago

Thank you for your response.
I did use the Astro deployment guide from the beginning and now have added the access-control-allow-origin. However, the issue hasn't been solved.
I troubleshooted further and realize that the issue is coming from the connection to the backend service.
I logged the response object in the astro server api and got the following?

survey id 67786179ec9d304a26b4f428

Jan 07 13:10:36

env http://**********production.up.railway.app/graphql

Jan 07 13:10:36

start of backend request

Jan 07 13:10:36

query Survey($surveyId: String!) {

Jan 07 13:10:36

survey(id: $surveyId) {

Jan 07 13:10:36

_id

Jan 07 13:10:36

title

Jan 07 13:10:36

funnelId

Jan 07 13:10:36

description

Jan 07 13:10:36

steps

Jan 07 13:10:36

initialStep

Jan 07 13:10:36

createdAt

Jan 07 13:10:36

updatedAt

Jan 07 13:10:36

}

Jan 07 13:10:36

}

Jan 07 13:10:36

Jan 07 13:10:36

request response Response {

Jan 07 13:10:36

[Symbol(realm)]: null,

Jan 07 13:10:36

[Symbol(state)]: {

Jan 07 13:10:36

aborted: false,

Jan 07 13:10:36

rangeRequested: false,

Jan 07 13:10:36

timingAllowPassed: true,

Jan 07 13:10:36

requestIncludesCredentials: false,

Jan 07 13:10:36

type: 'default',

Jan 07 13:10:36

status: 400,

Jan 07 13:10:36

timingInfo: {

Jan 07 13:10:36

startTime: 28857.333236694336,

Jan 07 13:10:36

redirectStartTime: 28857.333236694336,

Jan 07 13:10:36

redirectEndTime: 28882.33184814453,

Jan 07 13:10:36

postRedirectStartTime: 28882.33184814453,

Jan 07 13:10:36

finalServiceWorkerStartTime: 0,

Jan 07 13:10:36

finalNetworkResponseStartTime: 0,

Jan 07 13:10:36

finalNetworkRequestStartTime: 0,

Jan 07 13:10:36

endTime: 0,

Jan 07 13:10:36

encodedBodySize: 800,

Jan 07 13:10:36

decodedBodySize: 800,

Jan 07 13:10:36

finalConnectionTimingInfo: null

Jan 07 13:10:36

},

Jan 07 13:10:36

cacheState: '',

Jan 07 13:10:36

statusText: 'Bad Request',

Jan 07 13:10:36

headersList: HeadersList {

Jan 07 13:10:36

cookies: null,

Jan 07 13:10:36

[Symbol(headers map)]: [Map],

Jan 07 13:10:36

[Symbol(headers map sorted)]: null

Jan 07 13:10:36

},

Jan 07 13:10:36

urlList: [ [URL], [URL] ],

Jan 07 13:10:36

body: { stream: undefined }

Jan 07 13:10:36

},

Jan 07 13:10:36

[Symbol(headers)]: HeadersList {

Jan 07 13:10:36

cookies: null,

Jan 07 13:10:36

[Symbol(headers map)]: Map(10) {

Jan 07 13:10:36

'access-control-allow-origin' => [Object],

Jan 07 13:10:36

'content-length' => [Object],

Jan 07 13:10:36

'content-type' => [Object],

Jan 07 13:10:36

'date' => [Object],

Jan 07 13:10:36

'etag' => [Object],

Jan 07 13:10:36

'server' => [Object],

Jan 07 13:10:36

'x-clerk-auth-reason' => [Object],

Jan 07 13:10:36

'x-clerk-auth-status' => [Object],

Jan 07 13:10:36

'x-powered-by' => [Object],

Jan 07 13:10:36

'x-railway-request-id' => [Object]

Jan 07 13:10:36

},

Jan 07 13:10:36

[Symbol(headers map sorted)]: null

Jan 07 13:10:36

}

Jan 07 13:10:36

}

Jan 07 13:10:36

request response body ReadableStream { locked: false, state: 'readable', supportsBYOB: false }

Jan 07 13:10:36

request response json {

Jan 07 13:10:36

errors: [

Jan 07 13:10:36

{

Jan 07 13:10:36

message: "This operation has been blocked as a potential Cross-Site Request Forgery (CSRF). Please either specify a 'content-type' header (with a type that is not one of application/x-www-form-urlencoded, multipart/form-data, text/plain) or provide a non-empty value for one of the following headers: x-apollo-operation-name, apollo-require-preflight\n",

Jan 07 13:10:36

extensions: [Object]

Jan 07 13:10:36

}

Jan 07 13:10:36

]

Jan 07 13:10:36

}


Status changed to Awaiting Railway Response railway[bot] 6 months ago


6 months ago

Hey!

Seems like this is the actual error you're running into:

This operation has been blocked as a potential Cross-Site Request Forgery (CSRF).
Please either specify a 'content-type' header (with a type that is not one of application/x-www-form-urlencoded, multipart/form-data, text/plain) or provide a non-empty value for one of the following headers: x-apollo-operation-name, apollo-require-preflight\n

FYI this looks like an issue on your application's side that we do not control. Unfortunately we're unable to provide first-party support for issues unrelated to the Railway product or platform. Other communities such as Stackoverflow might be able to help you out further.


Status changed to Awaiting User Response railway[bot] 6 months ago


dannyhousefolios
PRO

6 months ago

That is not entirely the case. I found out that when I use the public address of the backend service, that is when I get the CSRF error. I fixed that. However, when I use the internal address, it fails for ECONNREFUSED.
TypeError: fetch failed

Jan 07 15:15:20

at node:internal/deps/undici/undici:12618:11

Jan 07 15:15:20

at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Jan 07 15:15:20

at async Module.GET (file:///app/dist/server/pages/api/surveys/_id_.astro.mjs:22:22)

Jan 07 15:15:20

at async renderEndpoint (file:///app/dist/server/chunks/astro/server_DbhpOjhr.mjs:391:18)

Jan 07 15:15:20

at async lastNext (file:///app/dist/server/chunks/_@astrojs-ssr-adapter_CvMmHByK.mjs:2660:23)

Jan 07 15:15:20

at async callMiddleware (file:///app/dist/server/chunks/_@astrojs-ssr-adapter_CvMmHByK.mjs:816:10)

Jan 07 15:15:20

at async RenderContext.render (file:///app/dist/server/chunks/_@astrojs-ssr-adapter_CvMmHByK.mjs:2704:22)

Jan 07 15:15:20

at async NodeApp.render (file:///app/dist/server/chunks/_@astrojs-ssr-adapter_CvMmHByK.mjs:3350:18)

Jan 07 15:15:20

at async file:///app/dist/server/chunks/_@astrojs-ssr-adapter_CvMmHByK.mjs:3715:30 {

Jan 07 15:15:20

cause: Error: connect ECONNREFUSED fd12:bf0f:d489::ac:762f:ab3:80

Jan 07 15:15:20

at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)

Jan 07 15:15:20

at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:128:17) {

Jan 07 15:15:20

errno: -111,

Jan 07 15:15:20

code: 'ECONNREFUSED',

Jan 07 15:15:20

syscall: 'connect',

Jan 07 15:15:20

address: 'fd12:bf0f:d489::ac:762f:ab3',

Jan 07 15:15:20

port: 80

Jan 07 15:15:20

}

Jan 07 15:15:20

}

I don't think that the issue is from my backend setup but rather a network config issue on railway. If not, why does the public address work whereas the internal address doesn't?


Status changed to Awaiting Railway Response railway[bot] 6 months ago


6 months ago

From your logs:

code: 'ECONNREFUSED',
syscall: 'connect',
address: 'fd12:bf0f:d489::ac:762f:ab3',
port: 80

Your backend service isn't running on port 80. It's running on port 8080 so you need to append that to your internal address (ex: agave-lms-backend.railway.internal)

CSRF errors have nothing to do with the platform. Looking at the original error message though - have you tried setting content-type=application/json in your request headers?


Status changed to Awaiting User Response railway[bot] 6 months ago


dannyhousefolios
PRO

6 months ago

That solved the issues. Thank you very much Ray!


Status changed to Awaiting Railway Response railway[bot] 6 months ago


Status changed to Solved ray-chen 6 months ago