Skip to content

Self-hosted: Email authentication not creating sessions after verification #1360

Description

@FarhanSE

Description

When using self-hosted(Digital Ocean Droplet) Cap Web with email authentication, users can successfully verify their email via OTP, but the authentication flow fails to create a session. After entering a valid OTP, users are redirected to /login-success which returns a 404 error, and no session is established.

Reproduction

  1. Start the Docker Compose stack: docker compose up -d
  2. Navigate to http://137.................. in a browser
  3. Enter an email address on the login page
  4. Enter the OTP code on the verification page
  5. Click "Verify"

After entering a valid OTP:

  1. NextAuth should create a session (adapter_createSession should be called)
  2. A session cookie should be set in the browser
  3. User should be redirected to the dashboard
  4. User should remain logged in

Additional Context

docker-compose.yml

version: "3.9"
services:
  cap-primary-db:
    image: mysql:8.0
    container_name: cap-primary-db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: [REDACTED]
      MYSQL_DATABASE: capdb
      MYSQL_USER: capuser
      MYSQL_PASSWORD: [REDACTED]
    volumes:
      - cap-so-selfhost_ps-mysql:/var/lib/mysql
    ports:
      - "3307:3306"
    networks:
      - cap-network

  cap-minio-storage:
    image: minio/minio:latest
    container_name: cap-minio-storage
    restart: unless-stopped
    environment:
      MINIO_ROOT_USER: ${CAP_AWS_ACCESS_KEY}
      MINIO_ROOT_PASSWORD: ${CAP_AWS_SECRET_KEY}
      MINIO_DEFAULT_BUCKETS: ${CAP_AWS_BUCKET}
    volumes:
      - cap-so-selfhost_minio-data:/data
    ports:
      - "3902:3902"
    command: server /data --console-address ":9001" --address ":3902"
    networks:
      - cap-network

  cap-web:
    image: ghcr.io/capsoftware/cap-web:latest
    container_name: cap-web
    depends_on:
      - cap-primary-db
      - cap-minio-storage
    restart: unless-stopped
    env_file:
      - .env
    expose:
      - "3000"
    networks:
      - cap-network
    volumes:
      - ./uploads:/app/public/uploads

  cap-nginx:
    image: nginx:alpine
    container_name: cap-nginx
    restart: unless-stopped
    depends_on:
      - cap-web
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    networks:
      - cap-network

volumes:
  cap-so-selfhost_ps-mysql:
  cap-so-selfhost_minio-data:

networks:
  cap-network:
    driver: bridge

.env

DATABASE CONFIG

DATABASE_URL=mysql://capuser:[REDACTED]@cap-primary-db:3306/capdb
DATABASE_ENCRYPTION_KEY=[REDACTED]

AUTH CONFIG

NEXTAUTH_SECRET=[REDACTED]
NEXTAUTH_URL=http://137.......
WEB_URL=http://137.184.........

STORAGE CONFIG

CAP_AWS_ACCESS_KEY=capS3root
CAP_AWS_SECRET_KEY=capS3root
CAP_AWS_BUCKET=capso
CAP_AWS_REGION=us-east-1
S3_PUBLIC_ENDPOINT=http://137.......:3902
S3_INTERNAL_ENDPOINT=http://cap-minio-storage:3902

EMAIL (RESEND) CONFIG

RESEND_API_KEY=[REDACTED]
RESEND_FROM_EMAIL=noreply@v...........m.com
RESEND_FROM_DOMAIN=va.............m.com

OTHER

NODE_ENV=production
CAP_TELEMETRY_DISABLED=true
NEXTAUTH_DEBUG=true

Logs:

cap-web  | [next-auth][warn][DEBUG_ENABLED] 
cap-web  | https://next-auth.js.org/warnings#debug_enabled
cap-web  | [next-auth][debug][adapter_getUserByEmail] { args: [ 'b..............@gmail.com' ] }
cap-web  | sendVerificationRequest
cap-web  | { identifier: 'b............@gmail.com', token: '957687' }
cap-web  | [next-auth][debug][adapter_createVerificationToken] {
cap-web  |   args: [
cap-web  |     {
cap-web  |       identifier: 'b...............@gmail.com',
cap-web  |       token: '39c0db562d59d28682f7dfa809f4c8ed2b746459987e482c830ce5f8da849113',
cap-web  |       expires: 2025-11-07T10:42:23.673Z
cap-web  |     }
cap-web  |   ]
cap-web  | }
cap-web  | {
cap-web  |   email: {
cap-web  |     '$$typeof': Symbol(react.transitional.element),
cap-web  |     type: {
cap-web  |       '$$typeof': Symbol(react.forward_ref),
cap-web  |       render: [Function (anonymous)],
cap-web  |       displayName: 'Html'
cap-web  |     },
cap-web  |     key: null,
cap-web  |     ref: null,
cap-web  |     props: { children: [Array] }
cap-web  |   }
cap-web  | }
cap-web  | [next-auth][warn][DEBUG_ENABLED] 
cap-web  | https://next-auth.js.org/warnings#debug_enabled
cap-web  | [next-auth][debug][adapter_useVerificationToken] {
cap-web  |   args: [
cap-web  |     {
cap-web  |       identifier: 'b..........@gmail.com',
cap-web  |       token: '39c0db562d59d28682f7dfa809f4c8ed2b746459987e482c830ce5f8da849113'
cap-web  |     }
cap-web  |   ]
cap-web  | }
cap-web  | [next-auth][debug][adapter_getUserByEmail] { args: [ 'b............@gmail.com' ] }
cap-web  | [next-auth][debug][adapter_getUserByEmail] { args: [ 'b............@gmail.com' ] }
cap-web  | [next-auth][debug][adapter_updateUser] {
cap-web  |   args: [
cap-web  |     { id: 'q1z9bk7n65hgk76', emailVerified: 2025-11-06T10:43:11.840Z }
cap-web  |   ]
cap-web  | }
cap-web  | timestamp=2025-11-06T10:43:12.260Z level=INFO fiber=#29 message="Using CAP_AWS_ACCESS_KEY and CAP_AWS_SECRET_KEY"

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions