Next.js Discord

Discord Forum

code: 'ERR_SSL_WRONG_VERSION_NUMBER' when generating feed.xml

Unanswered
adam.birds posted this in #help-forum
Open in Discord
So it works fine locally, but when in production (in a docker container, behind an nginx reverse proxy) we get the following error:
 ⨯ TypeError: fetch failed
    at node:internal/deps/undici/undici:13510:13
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async an (/app/.next/server/app/feed.xml/route.js:5:176608)
    at async /app/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:34666
    at async eS.execute (/app/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:25813)
    at async eS.handle (/app/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:35920)
    at async doRender (/app/node_modules/next/dist/server/base-server.js:1377:42)
    at async cacheEntry.responseCache.get.routeKind (/app/node_modules/next/dist/server/base-server.js:1599:28)
    at async NextNodeServer.renderToResponseWithComponentsImpl (/app/node_modules/next/dist/server/base-server.js:1507:28)
    at async NextNodeServer.renderPageComponent (/app/node_modules/next/dist/server/base-server.js:1924:24) {
  [cause]: [Error: 48822AE180770000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:354:
  ] {
    library: 'SSL routines',
    reason: 'wrong version number',
    code: 'ERR_SSL_WRONG_VERSION_NUMBER'
  }
}


below is my route.ts file:

export const dynamic = 'force-dynamic';

import assert from 'assert'
import * as cheerio from 'cheerio'
import { Feed } from 'feed'

export async function GET(req: Request) {
  // Public URL used for feed links (must be HTTPS in production)
  const siteUrl = process.env.NEXT_PUBLIC_SITE_URL
  if (!siteUrl) {
    throw Error('Missing NEXT_PUBLIC_SITE_URL environment variable')
  }

  // Internal URL used to fetch pages within the container
  const internalUrl = process.env.INTERNAL_SITE_URL
  if (!internalUrl) {
    throw Error('Missing INTERNAL_SITE_URL environment variable')
  }

  const author = {
    name: 'Joe Bloggs',
    email: 'joe@example.com',
  }

  const feed = new Feed({
    title: author.name,
    description:
      'I'm Joe, Im a software dveeloper.',
    author,
    id: siteUrl,
    link: siteUrl,
    image: `${siteUrl}/favicon.ico`,
    favicon: `${siteUrl}/favicon.ico`,
    copyright: `All rights reserved ${new Date().getFullYear()}`,
    feedLinks: {
      rss2: `${siteUrl}/feed.xml`,
    },
  })

  // Using require.context to fetch all articles – adjust this if needed based on your project setup
  const articleIds = require
    .context('../articles', true, /\/page\.mdx$/)
    .keys()
    .filter((key: string) => key.startsWith('./'))
    .map((key: string) => key.slice(2).replace(/\/page\.mdx$/, ''))

  for (const id of articleIds) {
    // Build the URL using the internal URL for fetch requests.
    const url = String(new URL(`/articles/${id}`, internalUrl))
    const response = await fetch(url)
    const html = await response.text()
    const $ = cheerio.load(html)

    const publicUrl = `${siteUrl}/articles/${id}`
    const article = $('article').first()
    const title = article.find('h1').first().text()
    const date = article.find('time').first().attr('datetime')
    const content = article.find('[data-mdx-content]').first().html()

    // Ensure the required elements are found.
    assert(typeof title === 'string')
    assert(typeof date === 'string')
    assert(typeof content === 'string')

    feed.addItem({
      title,
      id: publicUrl,
      link: publicUrl,
      content,
      author: [author],
      contributor: [author],
      date: new Date(date),
    })
  }

  return new Response(feed.rss2(), {
    status: 200,
    headers: {
      'content-type': 'application/xml',
      'cache-control': 's-maxage=31556952',
    },
  })
}


Any ideas on what the cause could be? More details in the comments.

3 Replies

I already tried adding the INTERNAL_SITE_URL to set to http://localhost:3000 in case it was trying to fetch internally but that didn't seem to help.
Can you check if all URLs are communicating through http:// and not https://?
If you’re not setting up a SSL certificate and Nginx can only serve http:// requests you can get this error