Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

I get Unauthorized error on every form request

default discord avatar
teneburulast year
16

Hi, I have a problem that I tried my best to fix in all ways possible.


I get a "You are not allowed to perform this action." on every document creation on all collections.



- I tried removing node_modules, pnpm store prune reinstall


- changing to version 3.28.1, 3.27.0, 3.26.0


- pnpx payload migrate:fresh, retry with fresh first user



Here's the shortened stack trace server error :


Request cookies: payload-token=REDACTED => middleware shows token in request
Request path: /admin/collections/media/create
{
  "level": 50,
  "time": 1742071317956,
  "pid": 3134,
  "hostname": "podmax",
  "name": "payload",
  "err": {
    "type": "Error",
    "message": "Unauthorized",
    "stack": "Error: Unauthorized
    at buildFormStateHandler (webpack-internal:///(rsc)/./node_modules/.pnpm/@payloadcms+ui@3.27.0_@types+react@19.0.10_monaco-editor@0.52.2_next@15.2.2_react-dom@1_1d4e4886e2c7f189dd15bb7272ea78a8/node_modules/@payloadcms/ui/dist/utilities/buildFormState.js:53:15)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async /root/podmax/node_modules/.pnpm/next@15.2.2_react-dom@19.0.0_react@19.0.0__react@19.0.0_sass@1.77.4/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:438:2357
    at async handleAction 
[...]
  "msg": "There was an error building form state"
}

after this error the request is replied with 403. in file upload, the error (see image) is showed as soon as file is in dropzone.



it works with :


curl 'https://redacted/api/media?depth=0&fallback-locale=null'   -X POST   -H 'Cookie: payload-token=redacted'   -F '_payload={"alt": "My image description"}'   -F 'file=./fichiers.png'


so the problem happens only when I'm using the web interface.


the next dev server is on alpine if that's relevant.



can someone help me 🙏 ? this is a very worrying problem, happens just as I am testing my production server for mondays deadline... I'll do whatever you want



please 😭



  • default discord avatar
    forrest.devlast year

    this usually has something to do with the cors or csrf. Make sure your next middle ware is setup for the correct domains and also the payload config

    cors & csrf

    cors: allowedOrigins,
      csrf: allowedOrigins,


    const allowedOrigins = [process.env.NEXT_PUBLIC_SERVER_URL].filter(Boolean);
  • default discord avatar
    teneburulast year

    i have a nginx reverse proxy in front of it it may be why, thank you so much i'll try that now

  • default discord avatar
    forrest.devlast year

    add this to the payload config and add any domains that might be accessing the panel into the allowOrigins array



    yeah, usually with any non regular setup where you have subdomains or another type of setup where the expected domain differs from where your accessing it from will give this type of error.



    also makesure to configure your next middleware as well

  • default discord avatar
    teneburulast year

    thank you so much i was so stressed i'm feeling better



    i'll try now i'll mention you if i cant find syntax



    or something

  • default discord avatar
    forrest.devlast year

    anytime, ping me if you need

  • default discord avatar
    teneburulast year

    thank you so much !!



    @418983916771213334

    seems like I'm not doing it well...



    payload config =


    const allowedOrigins = [
      process.env.NEXT_PUBLIC_BASE_URL,
      process.env.NEXT_PUBLIC_BASE_URL_ADMIN,
      'http://localhost:3000',
      'http://10.0.0.102:3000',
    ].filter(Boolean)
    
    
    export default buildConfig({
    ...
        },
      cors: allowedOrigins,
      csrf: allowedOrigins,


    middleware.ts =


    import { type NextRequest, NextResponse } from 'next/server'
    import { updateSession } from '@/utils/supabase/middleware'
    
    export async function middleware(request: NextRequest) {
      // Log cookies before processing
      console.log('Request cookies:', request.headers.get('cookie'));
      
      // Log the URL path to help identify which routes are being processed
      console.log('Request path:', request.nextUrl.pathname);
      
      const response = await updateSession(request)
      
      // Add CORS headers
      response.headers.set('Access-Control-Allow-Origin', 'https://myproductionserver.fr, http://127.0.0.1:3000, http://10.0.0.102:3000')
      response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
      response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization')
      response.headers.set('Access-Control-Allow-Credentials', 'true')
      
      // Add CSRF protection headers
      response.headers.set('X-Frame-Options', 'DENY')
      response.headers.set('X-Content-Type-Options', 'nosniff')
      response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
      response.headers.set('Cross-Origin-Opener-Policy', 'same-origin')
      
      return response
    }
    
    export const config = {
      matcher: [
        /*
         * Match all request paths except for the ones starting with:
         * - _next/static (static files)
         * - _next/image (image optimization files)
         * - favicon.ico (favicon file)
         * Feel free to modify this pattern to include more paths.
         */
        '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|glb)$).*)',
      ],
    }


    isnt this what you expected ?

  • default discord avatar
    forrest.devlast year

    ok thats a good start, is that not working for you yet? still same unauthorized errors?



    and this is coming from when you access it via the web interface? and whats the domain for the web interface?

  • default discord avatar
    teneburulast year

    still the same errors, even after deleting node_modules .next, creating first user again.


    errors happen when loading a file in an upload collection dropzone, and 403 response when hitting save



    the web interface does not have a separate domain its the auto complete that created two env variables ^^'



    the 10.0.0.102 is the final destination, the ssl cert A record points to the nginx reverse proxy main server, which matches the cert and proxies the request to 10.0.0.102:3000

  • default discord avatar
    forrest.devlast year

    i see and in the url for the webinterface your at

    http://10.0.0.102:3000

    ?

  • default discord avatar
    teneburulast year

    i don't understand what you mean i'm testing the web interface being correctly proxied so the url in my browser is the production server domain name, when starting pnpm dev I can see

    Network: http://10.0.0.102:3000

    as expected, the nginx reverse proxy sits in between and proxies all the headers



    https://prodname.com/admin -> http://10.0.0.102:3000/admin

    is happenign correctly

  • default discord avatar
    forrest.devlast year

    ah yes so the url is the production server domain.

    const allowedOrigins = [
      process.env.NEXT_PUBLIC_BASE_URL,
      process.env.NEXT_PUBLIC_BASE_URL_ADMIN,
      'http://localhost:3000',
      'http://10.0.0.102:3000',
    'https://productionserver.domain',
    ].filter(Boolean)

    make sure thats in here

  • default discord avatar
    teneburulast year

    🫡



    worked ! wtf that's weird NEXT_PUBLIC_BASE_URL was supposed to be it

  • default discord avatar
    forrest.devlast year

    these allowedOrigins should also be the same as what your using in the next middleware aswell. I would probably export that array so that you can reuse it.

  • default discord avatar
    teneburulast year

    yea



    do you have a kofi ?

  • default discord avatar
    forrest.devlast year

    well glad it worked for you, if NEXT_PUBLIC... was supposed to be it then i would also check your env vars are being loaded correctly as maybe thats why it wasnt working



    haha no, and no need, just here to support the community and get it back when i need

  • default discord avatar
    teneburulast year

    i'll look into it



    tysm i'll try to help around too



    dm me if u need anything

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.