vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.14k stars 27.02k forks source link

[NEXT-1190] TypeError: fetch failed in server componant since next 13.0.6 #44062

Closed sylvain-guehria closed 1 year ago

sylvain-guehria commented 1 year ago

Verify canary release

Provide environment information

Operating System: Platform: linux Arch: x64 Version: #62-Ubuntu SMP Tue Nov 22 19:54:14 UTC 2022 Binaries: Node: 18.12.0 npm: 8.19.2 Yarn: 1.22.19 pnpm: N/A Relevant packages: next: 13.0.6 eslint-config-next: 13.0.0 react: 18.2.0 react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

Data fetching (gS(S)P, getInitialProps)

Link to the code that reproduces this issue

https://github.com/sylvain-guehria/StockShop

To Reproduce

I log here : https://inventory-market.vercel.app/ and that it's

Describe the Bug

when I log, a server componant fetch data. This was working this morning but after installing next 13.0.6 I got this error only in prod :

error validating user TypeError: fetch failed at Object.fetch (/var/task/node_modules/next/dist/compiled/undici/index.js:1:26684) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async validateUser (/var/task/.next/server/app/page.js:740:21) at async HomePage (/var/task/.next/server/app/page.js:674:17) { cause: TypeError: Cannot read properties of undefined (reading 'reason') at makeAppropriateNetworkError (/var/task/node_modules/next/dist/compiled/undici/index.js:2:54604) at schemeFetch (/var/task/node_modules/next/dist/compiled/undici/index.js:2:30000) at /var/task/node_modules/next/dist/compiled/undici/index.js:2:28607 at mainFetch (/var/task/node_modules/next/dist/compiled/undici/index.js:2:29007) at httpRedirectFetch (/var/task/node_modules/next/dist/compiled/undici/index.js:2:33708) at httpFetch (/var/task/node_modules/next/dist/compiled/undici/index.js:2:32580) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async schemeFetch (/var/task/node_modules/next/dist/compiled/undici/index.js:2:30793) at async /var/task/node_modules/next/dist/compiled/undici/index.js:2:28601 at async mainFetch (/var/task/node_modules/next/dist/compiled/undici/index.js:2:28426) }

Expected Behavior

no fetch error, either the result is null or a string.

Which browser are you using? (if relevant)

chrome

How are you deploying your application? (if relevant)

vercel

NEXT-1190

Pnlvfx commented 1 year ago

Same

mapringg commented 1 year ago

I no longer see the code that you attached. Are you fetching one of the API route with fetch within getSeverSideProps because that is not possible?

sylvain-guehria commented 1 year ago

Sorry, I solved it by removing the fetch from the layout and put it in the page. I used the new way to fetch data in a server component.

But we should be able to fetch data in the layout. The problem came with the upgrade from Next 13.0.5 to 13.0.6

timheerwagen commented 1 year ago

I get the same error in Next.js version 13.1.2. Still using the pages directory. Whether locally or on the server, the behaviour remains the same. No external fetch requests work and not even external images can be loaded with sharp. With Next.js version 12 everything worked fine.

TypeError: fetch failed
   at Object.fetch (node:internal/deps/undici/undici:14062:11)
   at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
   at async imageOptimizer (node_modules\next\dist\server\image-optimizer.js:472:29

Has anyone found a workaround?

Anas-Nabulsi commented 1 year ago

I managed to solve this problem by using 127.0.0.1 instead of localhost in the fetch URL

timheerwagen commented 1 year ago

My current solution is to put the following at the beginning of next.config.js

const dns = require("dns");

dns.setDefaultResultOrder("ipv4first")

The reason is Node17/18 using ipv6 as default for localhost. https://github.com/node-fetch/node-fetch/issues/1624

professorhaseeb commented 1 year ago

I'm getting this error on next:12.3.3 deployed on Vercel, works fine locally though

trazyn commented 1 year ago

node: 18 next: 13.2.3 deployed on Vercel

TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:14062:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

change to nodejs 16 works fine 🙃

arjendevos commented 1 year ago

Still an issue:

{
  error: TypeError: fetch failed
      at Object.processResponse (node:internal/deps/undici/undici:7188:34)
      at node:internal/deps/undici/undici:7516:42
      at node:internal/process/task_queues:140:7
      at AsyncResource.runInAsyncScope (node:async_hooks:202:9)
      at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
    cause: Error: [object Object]
        at makeNetworkError (node:internal/deps/undici/undici:6317:51)
        at httpNetworkFetch (node:internal/deps/undici/undici:7810:16)
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
        at async httpNetworkOrCacheFetch (node:internal/deps/undici/undici:7703:33)
        at async httpFetch (node:internal/deps/undici/undici:7557:37)
        at async schemeFetch (node:internal/deps/undici/undici:7489:18)
        at async node:internal/deps/undici/undici:7342:20
        at async mainFetch (node:internal/deps/undici/undici:7338:20) {
      [cause]: undefined
    }
  }
}```

node: 18.0.0 and tested with node 16.19.1

```json
"@types/node": "18.15.3",
    "@types/react": "18.0.28",
    "@types/react-dom": "18.0.11",
    "eslint": "8.36.0",
    "eslint-config-next": "13.2.4",
    "next": "^13.2.4",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "sass": "^1.59.3",
    "typescript": "4.9.5"
Puharesource commented 1 year ago

For me this issue was caused by using self signed certificates for my development backend server. I simply added NODE_TLS_REJECT_UNAUTHORIZED=0 to my .env.local file located in the root of the project.

hk86 commented 1 year ago

Not an issue for me with version 13.2.4, but using the latest canary of 13.2.5 broke it on local Windows machine using dev.

error - TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11118:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.fn (C:\Projects\nextapp\sites\node_modules\next\dist\server\next-server.js:917:43)
    at async Router.execute (C:\Projects\nextapp\sites\node_modules\next\dist\server\router.js:293:32)
    ... 2 lines matching cause stack trace ...
    at async DevServer.handleRequestImpl (C:\Projects\nextapp\sites\node_modules\next\dist\server\base-server.js:437:20) {
  cause: InvalidArgumentError: invalid connection header
      at processHeader (node:internal/deps/undici/undici:6504:15)
      at new Request (node:internal/deps/undici/undici:6387:13)
      at [dispatch] (node:internal/deps/undici/undici:7359:25)
      at Intercept (node:internal/deps/undici/undici:7119:20)
      at [Intercepted Dispatch] (node:internal/deps/undici/undici:413:16)
      at Client.dispatch (node:internal/deps/undici/undici:429:44)
      at [dispatch] (node:internal/deps/undici/undici:648:32)
      at [Intercepted Dispatch] (node:internal/deps/undici/undici:406:33)
      at Pool.dispatch (node:internal/deps/undici/undici:429:44)
      at [dispatch] (node:internal/deps/undici/undici:8649:27)
      at Intercept (node:internal/deps/undici/undici:7119:20)
      at [Intercepted Dispatch] (node:internal/deps/undici/undici:413:16)
      at Agent.dispatch (node:internal/deps/undici/undici:429:44)
      at node:internal/deps/undici/undici:11010:83
      at new Promise (<anonymous>)
      at dispatch (node:internal/deps/undici/undici:11010:16)
      at httpNetworkFetch (node:internal/deps/undici/undici:10917:65)
      at httpNetworkOrCacheFetch (node:internal/deps/undici/undici:10819:39)
      at httpFetch (node:internal/deps/undici/undici:10671:43)
      at schemeFetch (node:internal/deps/undici/undici:10607:24)
      at node:internal/deps/undici/undici:10483:26
      at mainFetch (node:internal/deps/undici/undici:10500:11)
      at fetching (node:internal/deps/undici/undici:10457:7)
      at Agent.fetch2 (node:internal/deps/undici/undici:10337:20)
      at Object.fetch (node:internal/deps/undici/undici:11116:28)
      at fetch (node:internal/process/pre_execution:216:25)
      at Object.fn (C:\Projects\nextapp\sites\node_modules\next\dist\server\next-server.js:917:49)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async Router.execute (C:\Projects\nextapp\sites\node_modules\next\dist\server\router.js:293:32)
      at async DevServer.runImpl (C:\Projects\nextapp\sites\node_modules\next\dist\server\base-server.js:494:29)
      at async DevServer.run (C:\Projects\nextapp\sites\node_modules\next\dist\server\dev\next-dev-server.js:860:20)
      at async DevServer.handleRequestImpl (C:\Projects\nextapp\sites\node_modules\next\dist\server\base-server.js:437:20) {
    code: 'UND_ERR_INVALID_ARG'
  }
}
shriekdj commented 1 year ago

thanks buddy my issue solved

devhady commented 1 year ago

thanks buddy my issue solved

can u tell us how please ?

shriekdj commented 1 year ago

thanks buddy my issue solved

can u tell us how please ?

actually i had my backend api on localhost and this fetch was not working on http://localhost:8000 but, after some time it is working on at http://127.0.0.1:8000.

So that time I found out this, that nextjs 13 fetch does not work for localhost api

0x1h commented 1 year ago

Error appears most likely on node 18, I downgraded version to 16 and issue got fixed

miyahironari commented 1 year ago

I got the same errors and solved it.

e.g.

  const fetchUserInfo = async () => {
    const data = await fetch(
      process.env.API_URL + "/api/userIdByUsername/" + username
    )

    const json = await data.json()
    return json.user
  }

.env

API_URL=http://localhost:3000

run npm run build and npm run start

TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11413:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  cause: Error: connect ECONNREFUSED ::1:3000
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)
      at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
    errno: -61,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '::1',
    port: 3000
  }
}
[Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.] {
  digest: '3855851030'
}

then I tried modify .env following:

API_URL=http://127.0.0.1:3000

it works fine.

jabedzaman commented 1 year ago

My solution to this was keep your dev server running while deploying it on vercel or ceating a local build... 💀

kevlarr commented 1 year ago

I managed to solve this problem by using 127.0.0.1 instead of localhost in the fetch URL

@Anas-Nabulsi You are my hero, this resolved fetch issues in getting server-side props, as it did for others. Thanks for pointing it out.

sapomaro commented 1 year ago

I have similar error (ERR_INVALID_URL) with server-side fetch. Changing to 127.0.0.1 and other above-mentioned solutions don't work (haven't tried downgrading though). Calling external resources is blocked as well.

error - TypeError: Failed to parse URL from httр://localhost:3000/api/test
    at Object.fetch (node:internal/deps/undici/undici:14152:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async handler (webpack-internal:///(api)/./src/pages/api/checkout.js:8:20)
    at async Object.apiResolver (XXX\node_modules\next\dist\server\api-utils\node.js:372:9)
    at async DevServer.runApi (XXX\node_modules\next\dist\server\next-server.js:514:9)
    ... 5 lines matching cause stack trace ...
    at async XXX\node_modules\next\dist\server\base-server.js:157:99 {
  page: '/api/checkout',
  [cause]: TypeError [ERR_INVALID_URL]: Invalid URL
      at new NodeError (node:internal/errors:399:5)
      at URL.onParseError (node:internal/url:565:9)
      at new URL (node:internal/url:645:5)
      at new Request (node:internal/deps/undici/undici:6947:25)
      at fetch2 (node:internal/deps/undici/undici:13315:25)
      at Object.fetch (node:internal/deps/undici/undici:14150:18)
      at fetch (node:internal/process/pre_execution:241:25)
      at infoAPI (webpack-internal:///(api)/./src/modules/reporting/api/infoAPI.js:17:12)
      at handler (webpack-internal:///(api)/./src/pages/api/checkout.js:8:100)
      at Object.apiResolver (XXX\node_modules\next\dist\server\api-utils\node.js:372:15)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async DevServer.runApi (XXX\node_modules\next\dist\server\next-server.js:514:9)
      at async Object.fn (XXX\node_modules\next\dist\server\next-server.js:828:35)
      at async Router.execute (XXX\node_modules\next\dist\server\router.js:243:32)
      at async DevServer.runImpl (XXX\node_modules\next\dist\server\base-server.js:432:29)
      at async DevServer.run (XXX\node_modules\next\dist\server\dev\next-dev-server.js:831:20)
      at async DevServer.handleRequestImpl (XXX\node_modules\next\dist\server\base-server.js:375:20)
      at async XXX\node_modules\next\dist\server\base-server.js:157:99 {
    input: 'httр://localhost:3000/api/test',
    code: 'ERR_INVALID_URL'
  }
}

I'm running Next v13.2.4 (dev mode) on Node v19.4.0 (Windows 10).

More info: https://stackoverflow.com/questions/76148113/nextjs-server-side-fetch-typeerror-failed-to-parse-url-from-htt%d1%80-localhost

sapomaro commented 1 year ago

I have similar error (ERR_INVALID_URL) with server-side fetch. Changing to 127.0.0.1 and other above-mentioned solutions don't work (haven't tried downgrading though). Calling external resources is blocked as well.

It turned out that the URL was actually illegal. Sometimes invisible Unicode characters (like zero width non-joiner U+200C) can appear in unexpected places and it's kinda hard to hunt them down: https://invisible-characters.com/

yano3nora commented 1 year ago

I'm encountering the same error in a Docker environment.

I'm writing this for others as I couldn't find a similar workaround.

# .env
# https://next-auth.js.org/configuration/options#nextauth_url_internal
NEXTAUTH_URL_INTERNAL=http://127.0.0.1:3000
import { getServerSession } from 'next-auth'
import { authOptions } from 'pages/api/auth/[...nextauth]'

export const getServerSideProps = async (context) => {
  /**
   * using getServerSession instead of getSession (also api route)
   * @ref https://next-auth.js.org/configuration/nextjs#getserversession
   */
  const session = await getServerSession(context.req, context.res, authOptions)
  // ...
}
Error body ```sh nextjs-1 | [next-auth][error][CLIENT_FETCH_ERROR] nextjs-1 | https://next-auth.js.org/errors#client_fetch_error fetch failed { nextjs-1 | error: { nextjs-1 | message: 'fetch failed', nextjs-1 | stack: 'TypeError: fetch failed\n' + nextjs-1 | ' at Object.fetch (/app/node_modules/next/dist/compiled/undici/index.js:1:26669)\n' + nextjs-1 | ' at processTicksAndRejections (node:internal/process/task_queues:96:5)', nextjs-1 | name: 'TypeError' nextjs-1 | }, nextjs-1 | url: 'http://localhost:3000/api/auth/session', nextjs-1 | message: 'fetch failed' nextjs-1 | } ```
ijjk commented 1 year ago

Hi, since the original reproduction is no longer available, could someone who was experiencing this issue please confirm it is still an issue in the latest version of Next.js v13.4.1?

cyrine25 commented 1 year ago

yes i still have this issue : `TypeError: fetch failed at Object.fetch (/home/runner/work/next-ts-app/next-ts-app/node_modules/next/dist/compiled/undici/index.js:1:26669) at processTicksAndRejections (node:internal/process/task_queues:96:5) { cause: Error: connect ECONNREFUSED 127.0.0.1:3000 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16) at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) { errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 3000 } }

Error occurred prerendering page "/questions". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: fetch failed

Export encountered errors on following paths: /questions/page: /questions Error: Process completed with exit code 1.`

the fetch url i use when my local server is running : http://127.0.0.1:3000/data/questions.json next version : 13.4.1

timneutkens commented 1 year ago

@cyrine25 this is because you're trying to fetch from an internal api route during build, which is not supported.

arnasofc commented 1 year ago

what do you mean? Can you give an example and how to fix?

@cyrine25 this is because you're trying to fetch from an internal api route during build, which is not supported.

arnasofc commented 1 year ago

I fixed the issue by using http://127.0.0.1:3000 and adding to every fetch request (cache: 'no-store',)

tomsseisums commented 1 year ago

I feel like there are two issues here:

  1. The IPv6 being the default in later Node versions, which is still open: https://github.com/nodejs/undici/issues/1602
  2. The one I just opened in #49896 that Next loses exception information for low-level fetch related problems which can be extracted if try/catch'ing + console.error.
em1l1000 commented 1 year ago

I have this issue in 13.4.2. Update: The issue was fixed when I changed the backend link (process.env) from "http://" to "https://"

quiet-ocean commented 1 year ago

It might be caused sine the node version is higher than v18 where fetch is given by node. so you should use below version of node

joey-ma-steelgem commented 1 year ago

My current solution is to put the following at the beginning of next.config.js

const dns = require("dns");

dns.setDefaultResultOrder("ipv4first")

The reason is Node17/18 using ipv6 as default for localhost. https://github.com/node-fetch/node-fetch/issues/1624

This worked for me as well.

import dns from 'dns';

dns.setDefaultResultOrder('ipv4first');
offminded commented 1 year ago

I was having the same issue with node server in my dev env and fixed it using NODE_TLS_REJECT_UNAUTHORIZED=0 flag running the node server. My GraphQL server is using a self-signed certificate so the issue was related to nodejs issue with the SSL.

brandensilva commented 1 year ago

My experience was similar to @offminded in that I was trying to get HTTPS for my testing server api url when it was on HTTP. Be sure to check that if you get this.

askariali commented 1 year ago

I just got this error on Next.js v13.4.4 so I change my node version to 18.16 and It works like a charm

KoolP commented 1 year ago

Is this the way we should then use a conditional env variable for it: const API_URL = process.env.VERCEL_URL ?https://${process.env.VERCEL_URL} : process.env.NEXT_PUBLIC_API_URL; I am also looking forward to see Vercels preview and prod deploys to work. Or have different env folders for each?

adnanyangilic commented 1 year ago

I did three corrections to solve the same next.js 13.4 and asp.net core 6 api crud communication fetch error: 1- I put http port before https port definition in launchsettings.json, 2- I commented out use https redirection in Program.cs, 3-I changed url https localhost to url http and 127.0.0.1 in next.js file . I hope same corrections also help you..

sanalpanicker commented 1 year ago

it worked for my local. But we have dev and prod URLs. dev : https://org.dev.is prod : https://org.prod.is

But this whole thing fails in my CI/CD build. await fetch(${process.env.HOST}/api/bookmarks); what should this process.env.HOST be? Should it be my org.dev.is (dev path) or still be 127.0.0.1?

sanalpanicker commented 1 year ago

it worked for my local. But we have dev and prod URLs. dev : https://org.dev.is prod : https://org.prod.is

But this whole thing fails in my CI/CD build. await fetch(${process.env.HOST}/api/bookmarks); what should this process.env.HOST be? Should it be my org.dev.is (dev path) or still be 127.0.0.1?

oh https://github.com/vercel/next.js/discussions/48793#discussioncomment-5715951 I just read this and its new info!! API routes exist for your client side code, or 3rd parties that you might want to feed data to.

KoolP commented 1 year ago

Wow, @sanalpanicker, that was an excellent example you linked to! 🙌 It seems that in this thread, we might have been creating components that had a client-side parent, and everything was working smoothly. However, when we switched to a pure server-side frontend, things suddenly stopped working as they did before. As @timneutkens clarified in the beginning, this issue arises because we are attempting to fetch data from an internal API route during the build process, which is not supported . So to get a mental model right here, does this mean that we've been doing everything completely wrong if we use api routes that for example fetch data from an external api, and are in no need for serving it to any client side use?

I also had the idea of hiding some fetch calls (hide request endpoints and possible env variables) within our own 'proxy' API route, but if a component or page is on the server side and makes a fetch, it wouldn't even be visible on the client side? So I wouldn't need to use an own API route for the call.

sanalpanicker commented 1 year ago

@KoolP exactly!

jaredonline commented 1 year ago

I believe I am hitting this as well. I have the following:

async function getData() {
    const res = await fetch('http://127.0.0.1:3001/info/name', { cache: 'no-store' })

    if (!res.ok) {
      return {name: "No name"}
    }

    return res.json()
}

export default async function Hello() {
  const data = await getData();

  return (
    <div>
      <h1>Your name is: {data.name}</h1>
    </div>
  )
}

Any time I run npm run build I get the following:

#8 27.43 TypeError: fetch failed
#8 27.43     at Object.fetch (node:internal/deps/undici/undici:11457:11)
#8 27.43     at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
#8 27.43   cause: Error: connect ECONNREFUSED 127.0.0.1:3001
#8 27.43       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)
#8 27.43       at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
#8 27.43     errno: -111,
#8 27.43     code: 'ECONNREFUSED',
#8 27.43     syscall: 'connect',
#8 27.43     address: '127.0.0.1',
#8 27.43     port: 3001
#8 27.43   }
#8 27.43 }
#8 27.45
#8 27.45 Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
#8 27.45 TypeError: fetch failed
#8 27.45     at Object.fetch (node:internal/deps/undici/undici:11457:11)
#8 27.45     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
#8 27.45 - info Generating static pages (2/4)
#8 27.54 - info Generating static pages (3/4)
#8 27.55 - info Generating static pages (4/4)
#8 27.55
#8 27.55 > Export encountered errors on following paths:
#8 27.55    /page: /

My understanding is that the cache: no-store is supposed to instruct next to skip that fetch during the pre-render phase, but it doesn't seem to be helping.

I'm on Next.js v13.4.6

For additional context, this app I'm building will not have direct access to any database. All data access is via internal APIs, I so can't use the solution linked above.

I only get the error when trying to build within Docker, it works locally, but my understanding is that the fetch shouldn't be attempted in the build context at all. It should only be attempted when the page is being rendered.

sanalpanicker commented 1 year ago

I believe I am hitting this as well. I have the following:

async function getData() {
    const res = await fetch('http://127.0.0.1:3001/info/name', { cache: 'no-store' })

    if (!res.ok) {
      return {name: "No name"}
    }

    return res.json()
}

export default async function Hello() {
  const data = await getData();

  return (
    <div>
      <h1>Your name is: {data.name}</h1>
    </div>
  )
}

Any time I run npm run build I get the following:

#8 27.43 TypeError: fetch failed
#8 27.43     at Object.fetch (node:internal/deps/undici/undici:11457:11)
#8 27.43     at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
#8 27.43   cause: Error: connect ECONNREFUSED 127.0.0.1:3001
#8 27.43       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)
#8 27.43       at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
#8 27.43     errno: -111,
#8 27.43     code: 'ECONNREFUSED',
#8 27.43     syscall: 'connect',
#8 27.43     address: '127.0.0.1',
#8 27.43     port: 3001
#8 27.43   }
#8 27.43 }
#8 27.45
#8 27.45 Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
#8 27.45 TypeError: fetch failed
#8 27.45     at Object.fetch (node:internal/deps/undici/undici:11457:11)
#8 27.45     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
#8 27.45 - info Generating static pages (2/4)
#8 27.54 - info Generating static pages (3/4)
#8 27.55 - info Generating static pages (4/4)
#8 27.55
#8 27.55 > Export encountered errors on following paths:
#8 27.55  /page: /

My understanding is that the cache: no-store is supposed to instruct next to skip that fetch during the pre-render phase, but it doesn't seem to be helping.

I'm on Next.js v13.4.6

For additional context, this app I'm building will not have direct access to any database. All data access is via internal APIs, I so can't use the solution linked above.

I only get the error when trying to build within Docker, it works locally, but my understanding is that the fetch shouldn't be attempted in the build context at all. It should only be attempted when the page is being rendered.

read here - https://github.com/vercel/next.js/issues/44062#issuecomment-1592646952

jaredonline commented 1 year ago

@sanalpanicker I read that thread; how do I keep a fetch call from being attempted during the build phase? I don't have the option of switching to accessing the database directly.

LeandroVCastro commented 1 year ago

Wow, @sanalpanicker, that was an excellent example you linked to! 🙌 It seems that in this thread, we might have been creating components that had a client-side parent, and everything was working smoothly. However, when we switched to a pure server-side frontend, things suddenly stopped working as they did before. As @timneutkens clarified in the beginning, this issue arises because we are attempting to fetch data from an internal API route during the build process, which is not supported . So to get a mental model right here, does this mean that we've been doing everything completely wrong if we use api routes that for example fetch data from an external api, and are in no need for serving it to any client side use?

I also had the idea of hiding some fetch calls (hide request endpoints and possible env variables) within our own 'proxy' API route, but if a component or page is on the server side and makes a fetch, it wouldn't even be visible on the client side? So I wouldn't need to use an own API route for the call.

Are you suggesting to use a service to get data instead call an API route?

sanalpanicker commented 1 year ago

@LeandroVCastro "but my understanding is that the fetch shouldn't be attempted in the build context at all". This is a react server component and it will be prerendered during the build time. Read more here : https://nextjs.org/learn/foundations/how-nextjs-works/buildtime-and-runtime

if you want this to be done during runtime/request move this to a client component (mark "use client") probably in a useEffect - it will work.

KoolP commented 1 year ago

The main idea that I just tired to get a hold on is that if we try to call any own api route endpoint within our next app we should not try to manually change the calls to such examples as in this thread as : 'http://127.0.0.1:3000/' we want to use '/api/get-something' if we call our own api routes. Our aim is not to try to call any own api route endpoints by jumping out of the server and manually calling own server endpoints via the internet if we are all the time on server components anyway. Then if its client side we might need to use normal client side fetching with useEffect as @sanalpanicker mentions. @jaredonline @LeandroVCastro

kirilkirkov commented 1 year ago

I believe I am hitting this as well. I have the following:


async function getData() {

    const res = await fetch('http://127.0.0.1:3001/info/name', { cache: 'no-store' })

    if (!res.ok) {

      return {name: "No name"}

    }

    return res.json()

}

export default async function Hello() {

  const data = await getData();

  return (

    <div>

      <h1>Your name is: {data.name}</h1>

    </div>

  )

}

Any time I run npm run build I get the following:


#8 27.43 TypeError: fetch failed

#8 27.43     at Object.fetch (node:internal/deps/undici/undici:11457:11)

#8 27.43     at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {

#8 27.43   cause: Error: connect ECONNREFUSED 127.0.0.1:3001

#8 27.43       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)

#8 27.43       at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {

#8 27.43     errno: -111,

#8 27.43     code: 'ECONNREFUSED',

#8 27.43     syscall: 'connect',

#8 27.43     address: '127.0.0.1',

#8 27.43     port: 3001

#8 27.43   }

#8 27.43 }

#8 27.45

#8 27.45 Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error

#8 27.45 TypeError: fetch failed

#8 27.45     at Object.fetch (node:internal/deps/undici/undici:11457:11)

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

#8 27.45 - info Generating static pages (2/4)

#8 27.54 - info Generating static pages (3/4)

#8 27.55 - info Generating static pages (4/4)

#8 27.55

#8 27.55 > Export encountered errors on following paths:

#8 27.55  /page: /

My understanding is that the cache: no-store is supposed to instruct next to skip that fetch during the pre-render phase, but it doesn't seem to be helping.

I'm on Next.js v13.4.6

For additional context, this app I'm building will not have direct access to any database. All data access is via internal APIs, I so can't use the solution linked above.

I only get the error when trying to build within Docker, it works locally, but my understanding is that the fetch shouldn't be attempted in the build context at all. It should only be attempted when the page is being rendered.

did you find solution and what should we do when fetch data in server side?

jaredonline commented 1 year ago

@kirilkirkov I use a flag in process.env to detect build time environments and skip the call to fetch manually. It's annoying, but it works. Alternatively, you can use a non localhost http fetch that you know will be available (even if it returns a 404 or something) because the result doesn't matter as long as you use { cache: 'no-store' } the fetch will happen every time the page is rendered.

@sanalpanicker I understand now. There's a couple of things that make this confusing/frustrating. There are three ways fetch can happen, as far as I understand it.

  1. within a client component denoted by "use client". This fetch will always be run in the browser and will be skipped during build steps.
  2. within a server component while responding to a request. fetch will be called as part of rendering the response for the client.
  3. within a build environment. This fetch will always be called, even when the result will never be used.

The distinction between 2 and 3 is the confusing/frustrating part. Adding to my confusion was the fact that localhost and 127.0.0.1 are not available in my build environment. Switching to a HTTP server that is available all the time works just fine, and the response doesn't matter due to { cache: 'no-store' }, it'll be recomputed anyway.

The link you provided to @LeandroVCastro seems out of date as it talks about getStaticProps which can only be used with page routing. I'm using app routing. The distinction between the two in the documentation adds to confusion. There's a lot of places that seem out of date, or only reference page routing (even though for new apps it appears app routing is recommended).

Note that I was reading these docs which are difficult to follow and/or misleading:

I spent a lot of time in the docs trying to figure out how the build environment handles calls to fetch, but was unable to figure it out except through trial and error.

It'd be lovely if the docs explicitly called out this scenario - when you want to do a fetch in a server side component but DO NOT want to pre-render that fetch in the build environment (because it is not static and will change on every page load).

It would also be loverly if there was a configuration flag or an option we could send to fetch to indicate that this call shouldn't be done in the build environment, even if that means we have to provide a default value for the response for the rest of the pre-render to proceed.

In my use case I want data fetched in the server side as much as possible as it will use internal network routes to get it and reduce client-side loading screens. For some data fetching it in the client will be acceptable. Almost never do I want to fetch data and then pre-render it statically until the next deploy.

KoolP commented 1 year ago

@jaredonline @kirilkirkov Do you also have som fallback like error components if the fetch fails. Like just thinking if there should be one to make sure something is returned?

kirilkirkov commented 1 year ago

@KoolP No, i dont have. I am using fetch in my server components to get some data for the frontend, but when i make deploy with docker, the endpoint not works. This is good idea for the fallback and little time for the validation of the fetch function , but the bad here is that when the website is deployed, first minutes/seconds of the website will show wrong data, before the validation expire... Into the fetch function i am using my own route which is working with my database.. so will be good to have option on deploy to exclude this fetching and then when is deployed with the first request to make the cache from the api

jaredonline commented 1 year ago

@KoolP yes but that's good practice anyway - if you're fetching data from an external source it can fail at any time, so having a fallback makes sense

@kirilkirkov if you add the { cache: 'no-store' } option to fetch then it won't cache at all, and you don't have to worry about it showing stale/wrong data.