SSL wrong version number after switching between route groups
Unanswered
Black carpenter ant posted this in #help-forum
Black carpenter antOP
I am handling auth using route groups and upon logging out, I get the following error:
After I get this error, all of my requests return the same error but before changing the route group I don't get the error when doing the same requests.
failed to get redirect response TypeError: fetch failed
at node:internal/deps/undici/undici:12618:11
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async globalThis.fetch (/workspace/.next/server/chunks/6225.js:1:38529)
at async rp (/workspace/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:15:4325)
at async rm (/workspace/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:16:741)
at async rq (/workspace/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:18:1249)
at async doRender (/workspace/node_modules/next/dist/server/base-server.js:1376:30)
at async cacheEntry.responseCache.get.routeKind (/workspace/node_modules/next/dist/server/base-server.js:1537:28)
at async NextNodeServer.renderToResponseWithComponentsImpl (/workspace/node_modules/next/dist/server/base-server.js:1445:28)
at async NextNodeServer.renderPageComponent (/workspace/node_modules/next/dist/server/base-server.js:1842:24) {
cause: [Error: 40380321C27E0000: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'
}
}After I get this error, all of my requests return the same error but before changing the route group I don't get the error when doing the same requests.
69 Replies
Black carpenter antOP
I am handling the change of route groups in my middleware based on the presence of a cookie and all the logout button does is remove the cookie using a server action
export async function middleware(request: NextRequest) {
const session = request.cookies.get('kc_session');
const { pathname, search } = request.nextUrl;
if (pathname.startsWith('/legal')) {
return NextResponse.next();
}
if (pathname.startsWith('/_next')) {
return NextResponse.next();
}
try {
if (!session) {
throw new Error('Unauthorized');
}
return NextResponse.rewrite(
new URL(`/auth${pathname}${search}`, request.url),
);
} catch {
return NextResponse.rewrite(
new URL(`/noAuth${pathname}${search}`, request.url),
);
}
}All of this is working without issue when running locally but when I deploy it to DigitalOcean App Platform I start to face this issue
@Black carpenter ant All of this is working without issue when running locally but when I deploy it to DigitalOcean App Platform I start to face this issue
how do you host the site on digital ocean? do you use nginx?
Black carpenter antOP
It’s hosted using App Platform which is the PaaS, it uses heroku-buildpack-nodejs but I can’t find anything more specific as to what else they might use
@Black carpenter ant It’s hosted using App Platform which is the PaaS, it uses heroku-buildpack-nodejs but I can’t find anything more specific as to what else they might use
oh I have never used it, do you need to set anything?
and could you try to add a
and could you try to add a
console.log(request.url) in the middleware?Black carpenter antOP
All I need to do it push to GitHub and then it pulls the repo, builds and runs it. I've never had this issue in the past when deploying Next on App Platform and the only difference I think is the route groups. I'm just deploying the log change to see what it gives me
@Ray oh I have never used it, do you need to set anything?
and could you try to add a `console.log(request.url)` in the middleware?
Black carpenter antOP
The URL just before the error appears is
https://0.0.0.0:8080/loginAnd now I'm getting the error
Error: Failed to find Server Action after the original error appears@Black carpenter ant The URL just before the error appears is `https://0.0.0.0:8080/login`
Could you try to get the domain with request.header.get(“host”)?
and do
const proto = new URL(request).protocol
const host = request.header.get(“host”)
NextResponse.rewrite(‘${proto}//${host}/login’)
and do
const proto = new URL(request).protocol
const host = request.header.get(“host”)
NextResponse.rewrite(‘${proto}//${host}/login’)
@Ray Could you try to get the domain with request.header.get(“host”)?
and do
const proto = new URL(request).protocol
const host = request.header.get(“host”)
NextResponse.rewrite(‘${proto}//${host}/login’)
Black carpenter antOP
I end up with a 404 because the login is within a route group
@Black carpenter ant I end up with a 404 because the login is within a route group
Hmm could you try to adjust the pathname because I dont know how your routing look like
Black carpenter antOP
Yeah, I'm just trying that now, just waiting for it to deploy
It looks like it acts as a redirect and I'm not sure why. I'll visit
/ and because there's no cookie it'll redirect to /noAuth instead of doing it like is did previously with the rewrite and then it just ends up in a massive loop of /noAuth/noAuth/.../noAuth etc.@Black carpenter ant It looks like it acts as a redirect and I'm not sure why. I'll visit `/` and because there's no cookie it'll redirect to `/noAuth` instead of doing it like is did previously with the rewrite and then it just ends up in a massive loop of `/noAuth/noAuth/.../noAuth` etc.
Could you try again with this
NextResponse.rewrite(new URL(‘${proto}//${host}/pathname’))
NextResponse.rewrite(new URL(‘${proto}//${host}/pathname’))
@Ray Could you try again with this
NextResponse.rewrite(new URL(‘${proto}//${host}/pathname’))
Black carpenter antOP
Still getting the same loop issue
@Black carpenter ant Still getting the same loop issue
Hmm, let me try to deploy a site to it
@Black carpenter ant All I need to do it push to GitHub and then it pulls the repo, builds and runs it. I've never had this issue in the past when deploying Next on App Platform and the only difference I think is the route groups. I'm just deploying the log change to see what it gives me
You have other nextjs site working on it?
And it is also doing rewriting?
Black carpenter antOP
I don't think I do have any other Next sites using rewrites on this platform, no
I'm not sure if this is relevant, but the host from the headers is still the original domain while the request.url is showing
0.0.0.0 so that might be the cause of the loopBlack carpenter antOP
So the site loads under the noAuth rewrite but when I try to login, it sets the cookie as it should which changes to the auth rewrite except the rewrite doesn’t work, I get stuck on the noAuth pages and that’s when the SSL error happens
@Black carpenter ant So the site loads under the noAuth rewrite but when I try to login, it sets the cookie as it should which changes to the auth rewrite except the rewrite doesn’t work, I get stuck on the noAuth pages and that’s when the SSL error happens
Ok try adding this at the beginning of middleware
If (request.method === “POST”) return
If (request.method === “POST”) return
Revert back other
Black carpenter antOP
I'm no longer getting the SSL error after doing that but I'm still getting the
Failed to find Server Action error. I think the SSL error isn't happening because I can't call the login server action which is what causes the change in rewrite@Ray What is your next version?
Black carpenter antOP
14.1.2
@Black carpenter ant 14.1.2
Could you show the code of the action?
@Ray Could you show the code of the action?
Black carpenter antOP
Yeah, I've taken out the calls to my database but this is the rest of the action
export async function signin(formData: FormData) {
const email = formData.get('email');
const password = formData.get('password');
if (!email || email === '') {
throw new Error('Email is required');
}
if (!password || password === '') {
throw new Error('Password is required');
}
try {
const session = // Call to database that returns object
cookies().set(SESSION_COOKIE, session.secret, {
path: '/',
httpOnly: true,
sameSite: 'strict',
secure: true,
});
} catch (error) {
console.error(error);
throw new Error('Failed to sign in');
} finally {
redirect('/');
}
}Black carpenter antOP
No, I'm using Appwrite, it's a Firebase alternative
Ah
@Black carpenter ant No, I'm using Appwrite, it's a Firebase alternative
Are you importing the action from client component?
Black carpenter antOP
This specific action is being imported to a server component
@Black carpenter ant This specific action is being imported to a server component
Does it work on dev?
Black carpenter antOP
After adding the
if (request.method === 'POST') return; it stops working on dev, but without it there's no problems@Black carpenter ant After adding the `if (request.method === 'POST') return;` it stops working on dev, but without it there's no problems
Does it work if you return NextReponse.next()?
Black carpenter antOP
No, it still can't find the server action
I think the server action might need to rewrite as well because it's trying to post to
/login which is meant to rewrite to /noAuth/loginOh you are on /noAuth/login/page.tsx?
Black carpenter antOP
Yeah, so the page is located at /noAuth/login/page.tsx but it’s meant to be rewritten to /login/page.tsx
It all works until the rewrite changes to /auth/page.tsx for the dashboard page
@Black carpenter ant Yeah, so the page is located at /noAuth/login/page.tsx but it’s meant to be rewritten to /login/page.tsx
Try to add a rewrite inside the if block
I think the problem is the action returning a redirect response and the middleware is rewriting
Black carpenter antOP
Ah okay, let me have a try with that and see if it works
@Black carpenter ant Ah okay, let me have a try with that and see if it works
Btw, route group should look like this (auth) and (noAuth)
And I think you dont need to rewrite the response
And I think you dont need to rewrite the response
Black carpenter antOP
Yeah, I was realising that just now, I think I used the wrong terminology, I don't think I'm using route groups for this part of the site
Black carpenter antOP
I'm just deploying now after removing the redirect from the action. In order to redirect from
/login to / after the rewrite is changed, should I create a /auth/login/page.tsx that redirects to / so that it gets triggered after the rewrite? I'm struggling to wrap my head around how to properly redirect and rewrite in this instance@Black carpenter ant I'm just deploying now after removing the redirect from the action. In order to redirect from `/login` to `/` after the rewrite is changed, should I create a `/auth/login/page.tsx` that redirects to `/` so that it gets triggered after the rewrite? I'm struggling to wrap my head around how to properly redirect and rewrite in this instance
Would you consider using route group instead of rewriting
Black carpenter antOP
I'm not sure if that would work for what I'm trying to do, I'm trying to have it so that
/ will change depending on if the user is currently logged in or not, so it'll show a landing screen if logged out and a dashboard if logged inAh ok
Does the action and rewriting work without using redirect()?
Black carpenter antOP
It doesn't look like it, no. I've just tried it and the first time calling the action it worked fine and set the cookie but now it's still showing the
/noAuth pages but trying to call the server action again results in Failed to find Server Action@Black carpenter ant It doesn't look like it, no. I've just tried it and the first time calling the action it worked fine and set the cookie but now it's still showing the `/noAuth` pages but trying to call the server action again results in `Failed to find Server Action`
could you show a screenshot of your folder structure?
@Ray could you show a screenshot of your folder structure?
Black carpenter antOP
@Black carpenter ant Click to see attachment
when visiting "/" it show /dashboard for authenticated user and /landing for unauthenticated?
Black carpenter antOP
That's the plan, it's meant to show
/auth/(dashboard)/page.tsx for authed users and /noAuth/page.tsx for unauthedapp/(noAuth)/login/page.tsxapp/(noAuth)/landing/page.tsxapp/(noAuth)/forgot/page.tsxapp/(auth)/dashboard/page.tsxapp/(auth)/logout/page.tsxapp/(auth)/staff/page.tsximport { NextRequest, NextResponse } from "next/server";
export async function middleware(request: NextRequest) {
const session = request.cookies.get("kc_session");
const { pathname, search } = request.nextUrl;
if (pathname.startsWith("/legal")) {
return NextResponse.next();
}
if (pathname.startsWith("/_next")) {
return NextResponse.next();
}
if (pathname === "/" && session) {
return NextResponse.rewrite(new URL("/dashboard", request.url));
}
}I think this would be alot easier
Black carpenter antOP
I had thought about this but (probably should have shown this before) /dashboard has A LOT more pages
And they go down even further etc.
could you make those sub route under /dashboard?
so you could check the pathname startWith /dashboard in middleware
I think you only need to rewrite on "/"? but you need to protect the route
Or add those route to an array
import { NextRequest, NextResponse } from "next/server";
const protectedRoute = ['/account', '/album', '/artist']
export async function middleware(request: NextRequest) {
const session = request.cookies.get("kc_session");
const { pathname, search } = request.nextUrl;
if (pathname.startsWith("/legal")) {
return NextResponse.next();
}
if (pathname.startsWith("/_next")) {
return NextResponse.next();
}
if (pathname === "/" && session) {
return NextResponse.rewrite(new URL("/dashboard", request.url));
}
if (!session && protectedRoute.include(pathname)) {
return NextResponse.redirect(new URL("/login", request.url))
}
}Black carpenter antOP
I'm just trying one more idea that I had but if it doesn't work then I'll definitely be going with what you've suggested
Black carpenter antOP
I thought it might have been related to route caching, sadly not. I'm going to change it to what you suggested, thank you!