payload icon indicating copy to clipboard operation
payload copied to clipboard

Can't update fields of an already uploaded media using the S3 adapter

Open fofoy opened this issue 1 year ago • 12 comments
trafficstars

Link to reproduction

No response

Payload Version

3.0.0-beta.56

Node Version

20.12.2

Next.js Version

15.0.0-rc.0

Describe the Bug

Whenever I want to update a field (e.g. Alt field), I get a 500 error when I try to submit the form.

Here is the log from the console image

Reproduction Steps

Install Payload v3.0.0-beta.56 with the default Media Collection Install @payloadcms/storage-s3 v3.0.0-beta.56 Set up S3 storage (I tried both on minIO and AWS S3 and I get the same behavior) Upload a first Media Update the Alt field and submit the form

Adapters and Plugins

@payloadcms/db-postgres v3.0.0-beta.56 @payloadcms/storage-s3 v3.0.0-beta.56

fofoy avatar Jul 05 '24 12:07 fofoy

Any news on this one ? Is there anything I can help you with @PatrikKozak ?

fofoy avatar Aug 07 '24 12:08 fofoy

Hey @fofoy - we'll get right on this!

PatrikKozak avatar Aug 07 '24 14:08 PatrikKozak

Hi @fofoy - I did some testing on my end and was not able to reproduce the above issue.

It may have something to do with your S3 storage setup - do you have a reverse proxy setup?

Is this purely local?

Just want to get some additional information before I can dig deeper into this - thank you!

PatrikKozak avatar Aug 08 '24 13:08 PatrikKozak

Hi @PatrikKozak I have the same issue in local (using a dockerized MinIO instance) and on my staging environment using an AWS S3 bucket so it doesn't seem to be a setup issue.

fofoy avatar Aug 08 '24 14:08 fofoy

@fofoy Thanks for the info - hmm unfortunately there isn't enough here to fully understand what could be causing this issue.

A couple things though, could you try and log out some of the info in that function where the error is coming from (in your node_modules) - this may be able to give us some more information

Also, could you update your payload packages versions to latest (just in case) - I'd like to get to the bottom of this but just will need more info to continue

PatrikKozak avatar Aug 08 '24 15:08 PatrikKozak

@PatrikKozak Thanks, I had the time to update my project to latest beta version 91 and the problem remains, I'll dig further to see where it's going wrong and I'll let you know.

fofoy avatar Aug 27 '24 12:08 fofoy

Hi @PatrikKozak here is the result of logging the Promise getExternalFile on line 41 of generateFileData.js file:

Promise {
  <pending>,
  [Symbol(async_id_symbol)]: 652801,
  [Symbol(trigger_async_id_symbol)]: 652790,
  [Symbol(kResourceStore)]: {
    url: {
      pathname: '/api/media/c26034b9-71ab-4e88-8ff1-2dfc5a980261',
      search: '?depth=0&fallback-locale=null'
    },
    headers: [Getter],
    cookies: [Getter],
    mutableCookies: [Getter],
    draftMode: [Getter],
    reactLoadableManifest: {},
    assetPrefix: '',
    afterContext: undefined,
    isHmrRefresh: undefined,
    serverComponentsHmrCache: undefined
  },
  [Symbol(kResourceStore)]: {
    isStaticGeneration: false,
    page: '/(payload)/api/[...slug]/route',
    fallbackRouteParams: null,
    route: '/api/[...slug]',
    incrementalCache: IncrementalCache {
      locks: Map(0) {},
      unlocks: Map(0) {},
      hasCustomCacheHandler: false,
      dev: true,
      disableForTestmode: false,
      minimalMode: false,
      requestHeaders: [Object],
      requestProtocol: 'https',
      allowedRevalidateHeaderKeys: undefined,
      prerenderManifest: [Object],
      revalidateTimings: [SharedRevalidateTimings],
      fetchCacheKeyPrefix: '',
      cacheHandler: [FileSystemCache]
    },
    isRevalidate: false,
    isPrerendering: undefined,
    fetchCache: undefined,
    isOnDemandRevalidate: undefined,
    isDraftMode: undefined,
    requestEndedState: undefined,
    revalidate: 0,
    tags: [
      '_N_T_/layout',
      '_N_T_/(payload)/layout',
      '_N_T_/(payload)/api/layout',
      '_N_T_/(payload)/api/[...slug]/layout',
      '_N_T_/(payload)/api/[...slug]/route',
      '_N_T_/api/media/c26034b9-71ab-4e88-8ff1-2dfc5a980261'
    ],
    nextFetchId: 2
  },
  [Symbol(kResourceStore)]: undefined,
  [Symbol(kResourceStore)]: undefined,
  [Symbol(kResourceStore)]: undefined,
  [Symbol(kResourceStore)]: { isAppRoute: true, isAction: false }
}

and here is the actual error when trying to fetch the file :

TypeError: fetch failed
     at node:internal/deps/undici/undici:12618:11
     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
     at async getExternalFile (webpack-internal:///(rsc)/../node_modules/.pnpm/[email protected][email protected][email protected][email protected]
 a48-202_bgnc5eiwwsaz2mukappcno4s3m/node_modules/payload/dist/uploads/getExternalFile.js:18:21) {
   cause: Error: connect ECONNREFUSED 127.0.0.1:443
       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1605:16)
       at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
     errno: -111,
     code: 'ECONNREFUSED',
     syscall: 'connect',
     address: '127.0.0.1',
     port: 443
   }
 }
  ⨯ unhandledRejection: TypeError: fetch failed
     at node:internal/deps/undici/undici:12618:11
     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
     at async getExternalFile (webpack-internal:///(rsc)/../node_modules/.pnpm/[email protected][email protected][email protected][email protected]
 a48-202_bgnc5eiwwsaz2mukappcno4s3m/node_modules/payload/dist/uploads/getExternalFile.js:18:21) {
   cause: Error: connect ECONNREFUSED 127.0.0.1:443
       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1605:16)
       at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
     errno: -111,
     code: 'ECONNREFUSED',
     syscall: 'connect',
     address: '127.0.0.1',
     port: 443
   }
 }
  ⨯ unhandledRejection: TypeError: fetch failed
     at node:internal/deps/undici/undici:12618:11
     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
     at async getExternalFile (webpack-internal:///(rsc)/../node_modules/.pnpm/[email protected][email protected][email protected][email protected]
 a48-202_bgnc5eiwwsaz2mukappcno4s3m/node_modules/payload/dist/uploads/getExternalFile.js:18:21) {
   cause: Error: connect ECONNREFUSED 127.0.0.1:443
       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1605:16)
       at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
     errno: -111,
     code: 'ECONNREFUSED',
     syscall: 'connect',
     address: '127.0.0.1',
     port: 443
   }
 }

So it seems like it's something to do with the network. I'm running everything in Docker with several containers for the postgres db, the S3 instance (minIO) and the payload admin but it also does the same on our dev cluster (kubernetes) with an AWS S3 instance connected to it.

fofoy avatar Sep 23 '24 13:09 fofoy

Hi @PatrikKozak and @fofoy

I'm having the same problem as well. I can't edit any fields of an already uploaded file, and I got the same error as described above.

We also run our environments in kubernetes and we use Google cloud storage for storing files. I have however noticed that when I'm running payload locally (and still using google cloud storage for storing files) it works. When I'm running payload in docker I get the same error we got in our kubernetes environments.

@fofoy Have you found any temporary workaround for this problem?

nickejoha avatar Oct 17 '24 07:10 nickejoha

Hi @nickejoha, I didn't have the time to dig any further than this yet as I need to make progress on my current project but that's definitely something that needs to be sorted, I'll try to invest more time in a bit.

fofoy avatar Oct 17 '24 07:10 fofoy

I also attempted to recreate this issue, but I was unable to. I'm not sure there's much more we can do on our end to troubleshoot this.

Please try and recreate this in the latest beta to ensure it is still an issue.

denolfe avatar Oct 28 '24 19:10 denolfe

Hi @denolfe, I updated to the latest version of beta v122 and the same problem remains, let me know if I can help you in any way to help you debug this.

fofoy avatar Oct 31 '24 08:10 fofoy

This issue has been marked as stale due to lack of activity.

To keep this issue open, please indicate that it is still relevant in a comment below.

github-actions[bot] avatar Dec 13 '24 05:12 github-actions[bot]

This issue was automatically closed due to lack of activity.

github-actions[bot] avatar Dec 21 '24 05:12 github-actions[bot]

@denolfe @fofoy I think we have found the issue here and we have implemented a workaround.

In short, the problem in our case seems to be connected our firewall in Google cloud plattform and locally that we use a different external port in our docker build.

The problem here seems to be that when we edit a field of media file that has been uploaded already, payload tries to fetch the file but the fetch fails. The problem in our case was that when payload tries to fetch the file, it uses the external url which works fine when used from a frontend client or when running a docker config that doesn't alter the ports, but because the request is executed from the container itself the url is invalid. In our local docker config the external url is localhost:3077, but inside the container the app runs on port 3000. So when we access file from outside the container localhost:3077 is valid, but when trying to fetch the same file from inside the container the url is invalid because the application runs on port 3000. The problem in our Google cloud plattform was due to the same fact that the external url isn't valid from inside the cluster.

So with that figured out we implemented a bit of a hack as a workaround. By temporarily changing the files url to a valid url (from the containers perspective) with a hook, and the error is gone and editing the file works :)

import { CollectionBeforeOperationHook, CollectionBeforeReadHook } from 'payload'

const fixMediaUrl = (req: any) => {
  if (req.data?.url) {
    const prefix = process.env.CMS_INTERNAL_URL || ''
    if (req.data.url.startsWith('/')) {
      req.data.url = prefix + req.data.url
    }
    if (req.data?.sizes) {
      for (const key in req.data.sizes) {
        if (req.data.sizes[key].url?.startsWith('/')) {
          req.data.sizes[key].url = prefix + req.data.sizes[key].url
        }
      }
    }
  }
}

export const fixMediaUrlOperation: CollectionBeforeOperationHook = async ({ req }) =>
  fixMediaUrl(req)

export const fixMediaUrlRead: CollectionBeforeReadHook = async ({ req }) => fixMediaUrl(req)

nickejoha avatar Dec 22 '24 19:12 nickejoha

Thanks @nickejoha for sharing your experience. I also encountered this issue with the same setup (Local dev: VSCode DevContainer + payloadcms & minio behind nginx; Production: self-hosted Openshift cluster, payloadcms & self-hosted S3 behind nginx). I thought my issue was related to the headers (#5159), but it was because the payloadcms server attempted to fetch the media using the request's origin which is inaccessible from server side because of the proxy, but accessible in client side.

My workaround

// src/collection/Media.ts 

// this is our Upload collection
const Media: CollectionConfig { 
  // ...snipped other props...
 upload: { /**...**/ },
 fields: [
    {
      name: 'caption',
      type: 'richText',
    },
  ],

  // workaround
  hooks: {
    beforeOperation: [
      (args) => {
        if (args.operation === 'update') {
          const cmsInternalUrl = process.env.CMS_INTERNAL_URL;
          args.req.headers.set('origin', cmsInternalUrl);
        }
      }
    ]
  }
}
# .devcontainer/local.env
CMS_INTERNAL_URL=http://development:3000 #my dev container's name is development
S3_BUCKET=my-minio-bucket-name
S3_ACCESS_KEY_ID=my-minio-user
S3_SECRET_ACCESS_KEY=my-minio-password
S3_ENDPOINT=http://minio:9000
S3_REGION=dummy
COLLECTIONS_MEDIA_PREFIX=my/media/prefix

# openshift/production.env
CMS_INTERNAL_URL=http://my-payloadcms-svc.my-ocp-namespace

Our setup:

Nginx.conf
// .devcontainer/nginx.conf
server {
    listen       8080;
    server_name  localhost;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://development:3000;
        # uncomment for production
        # proxy_pass http://my-payloadcms-svc.my-ocp-namespace

        # limit to 50MB file uploads
        client_max_body_size 50M;

        # for live preview
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
payload.config.ts / package.json
// payload.config.ts
export default buildConfig({
  // ... snipped...
  collections: [
    /** other collections **/
    Media
  ],
  plugins: [
    s3Storage({
      collections: {
        media: {
          prefix: process.env.COLLECTIONS_MEDIA_PREFIX ?? '',
        },
      },
      bucket: process.env.S3_BUCKET ?? '',
      config: {
        credentials: {
          accessKeyId: process.env.S3_ACCESS_KEY_ID ?? '',
          secretAccessKey: process.env.S3_SECRET_ACCESS_KEY ?? '',
        },
        endpoint: process.env.S3_ENDPOINT ?? '',
        region: process.env.S3_REGION ?? '',
        forcePathStyle: true,
        ...((process.env.S3_SKIP_SSL_VERIFICATION ?? 'false') === 'false'
          ? {}
          : {
              requestHandler: new NodeHttpHandler({
                httpsAgent: new https.Agent({
                  rejectUnauthorized: false,
                }),
              }),
            }),
      },
    })
})
// package.json

  "dependencies": {
    // other dependencies
    "@payloadcms/storage-s3": "^3.23.0",
    "payload": "^3.23.0"
  }  
minio-compose.yml
// minio-compose.yml
services:
  minio:
    image: quay.io/minio/minio
    container_name: minio
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio-data:/data
    environment:
      MINIO_ROOT_USER: my-minio-user
      MINIO_ROOT_PASSWORD: my-minio-password
    command: server /data --console-address ":9001"
    healthcheck:
      test: ["CMD", "mc", "ready", "local"]
      interval: 5s
      timeout: 5s
      retries: 5

  minio_create_buckets:
    image: minio/mc
    depends_on:
      - minio
    entrypoint: >
      /bin/sh -c "
      /usr/bin/mc alias set dev_minio http://minio:9000 my-minio-user my-minio-password;
      /usr/bin/mc ready dev_minio;
      /usr/bin/mc mb dev_minio/my-minio-bucket-name;
      exit 0;
      "
volumes:
  minio-data:

@denolfe So I think the way to replicate it is (using above setup):

  1. Create new Payload project
  2. Create the src/collections/Media.ts as the Upload collection (without the above workaround)
  3. Update payload.config.ts to use the S3 storage adapter
  4. Setup minio as the S3 storage via docker-compose
  5. Setup nginx via docker-compose with above configuration
  6. Start project pnpm dev
  7. Verify: can upload media via http://localhost:3000/admin/collections/media
  8. Verify: can edit the caption of the uploaded media via http://localhost:3000
  9. Verify: can upload media via the Nginx Proxy http://localhost:8080/admin/collections/media
  10. [BUG] Edit the caption of the uploaded media via Nginx Proxy http://localhost:8080/admin/collections/media. Server will raise a HTTP 500 error. Expected behavior: should be able to edit the caption
Error logs
[02:55:12] ERROR: There was a problem while uploading the file. fetch failed
    err: {
      "type": "FileRetrievalError",
      "message": "There was a problem while uploading the file. fetch failed",
      "stack":
          FileRetrievalError: There was a problem while uploading the file. fetch failed
              at generateFileData (/workspaces/myproject/monorepo/javascript/apps/payloadcms/.next/server/chunks/ssr/bdfa7_payload_dist_uploads_ff2765._.js:1510:19)
              at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
              at async updateByIDOperation (/workspaces/myproject/monorepo/javascript/apps/payloadcms/.next/server/chunks/ssr/bdfa7_payload_dist_collections_53370e._.js:3514:61)
              at async updateByIDHandler (/workspaces/myproject/monorepo/javascript/apps/payloadcms/.next/server/chunks/ssr/bdfa7_payload_dist_collections_53370e._.js:3606:17)
              at async handleEndpoints (/workspaces/myproject/monorepo/javascript/apps/payloadcms/.next/server/chunks/bdfa7_payload_dist_utilities_309618._.js:4613:26)
              at async /workspaces/myproject/monorepo/javascript/apps/payloadcms/.next/server/chunks/08b5e__pnpm_7ba201._.js:76608:26
              at async AppRouteRouteModule.do (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:10:32847)
              at async AppRouteRouteModule.handle (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:10:39868)
              at async doRender (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/base-server.js:1452:42)
              at async responseGenerator (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/base-server.js:1822:28)
              at async DevServer.renderToResponseWithComponentsImpl (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/base-server.js:1832:28)
              at async DevServer.renderPageComponent (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/base-server.js:2259:24)
              at async DevServer.renderToResponseImpl (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/base-server.js:2297:32)
              at async DevServer.pipeImpl (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/base-server.js:959:25)
              at async NextNodeServer.handleCatchallRenderRequest (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/next-server.js:281:17)
              at async DevServer.handleRequestImpl (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/base-server.js:853:17)
              at async /workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/dev/next-dev-server.js:371:20
              at async Span.traceAsyncFn (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/trace/trace.js:153:20)
              at async DevServer.handleRequest (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/dev/next-dev-server.js:368:24)
              at async invokeRender (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/lib/router-server.js:230:21)
              at async handleRequest (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/lib/router-server.js:408:24)
              at async requestHandlerImpl (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/lib/router-server.js:432:13)
              at async Server.requestListener (/workspaces/myproject/monorepo/javascript/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]_react-dom@19_xswngbf4keqk7f2jndmwiaenwy/node_modules/next/dist/server/lib/start-server.js:146:13)
      "data": null,
      "isOperational": true,
      "isPublic": false,
      "status": 500,
      "name": "FileRetrievalError"
    }

Again, my guess for the root cause is because Payloadcms is constructing the fetch URL from the request headers origin, which is inaccessible from the server side because of the nginx proxy (http://localhost:3000 vs http://localhost:8080)

Sorry for the long post. Maybe if I have time, I can create a repository for replication.

Thank you both.

greenlover1991 avatar Feb 21 '25 03:02 greenlover1991

I'm running in the same issue, also with MinIO. I will open a PR that fixes this.

eduhdev12 avatar Mar 03 '25 13:03 eduhdev12

I'm also experiencing the same issue; I'm using the S3 Adapter with a Cloudflare R2 bucket, and everything works fine when it comes to creating, reading, and deleting operations, but update does not work. Here is my error printout when I try to update the "description" field:

[01:56:38] ERROR: There was a problem while uploading the file. Blocked unsafe attempt to http://localhost:6002/api/media/file/SCR-20250523-jnsh.png
    err: {
      "type": "FileRetrievalError",
      "message": "There was a problem while uploading the file. Blocked unsafe attempt to http://localhost:6002/api/media/file/SCR-20250523-jnsh.png",
      "stack":
          FileRetrievalError: There was a problem while uploading the file. Blocked unsafe attempt to http://localhost:6002/api/media/file/SCR-20250523-jnsh.png
              at generateFileData (file:///Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/payload/dist/uploads/generateFileData.js:53:19)
              at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
              at async updateByIDOperation (file:///Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/payload/dist/collections/operations/updateByID.js:80:61)
              at async updateByIDHandler (file:///Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/payload/dist/collections/endpoints/updateByID.js:16:17)
              at async handleEndpoints (file:///Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/payload/dist/utilities/handleEndpoints.js:169:26)
              at async /Users/firatciftci/Developer/misc/artsumer/.next/server/chunks/node_modules__pnpm_94f68aa0._.js:29799:26
              at async AppRouteRouteModule.do (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.dev.js:26:34112)
              at async AppRouteRouteModule.handle (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.dev.js:26:41338)
              at async doRender (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/base-server.js:1518:42)
              at async DevServer.renderToResponseWithComponentsImpl (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/base-server.js:1920:28)
              at async DevServer.renderPageComponent (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/base-server.js:2408:24)
              at async DevServer.renderToResponseImpl (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/base-server.js:2445:32)
              at async DevServer.pipeImpl (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/base-server.js:1008:25)
              at async NextNodeServer.handleCatchallRenderRequest (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/next-server.js:305:17)
              at async DevServer.handleRequestImpl (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/base-server.js:900:17)
              at async /Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/dev/next-dev-server.js:371:20
              at async Span.traceAsyncFn (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/trace/trace.js:157:20)
              at async DevServer.handleRequest (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/dev/next-dev-server.js:368:24)
              at async invokeRender (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/lib/router-server.js:237:21)
              at async handleRequest (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/lib/router-server.js:428:24)
              at async requestHandlerImpl (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/lib/router-server.js:452:13)
              at async Server.requestListener (/Users/firatciftci/Developer/misc/artsumer/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]_b5160444ab580599d92acf97540046d0/node_modules/next/dist/server/lib/start-server.js:158:13)
      "data": null,
      "isOperational": true,
      "isPublic": false,
      "status": 500,
      "name": "FileRetrievalError"
    }
 PATCH /api/media/1977?depth=0&fallback-locale=null 500 in 406ms

Important to note that, if I turn off the upload.filesRequiredOnCreate flag, create a new Media item with no image, and then edit its "description" field, I have no issues updating it. This only occurs when there is an image attached.

I have also checked the Content-Length and the "origin" header of the update request, and those seem to be all fine.

firatciftci avatar Jun 18 '25 06:06 firatciftci

Happens also to me on local storage and also on GCS storage so it's not related to S3 Look at https://github.com/payloadcms/payload/pull/12622#issuecomment-2987818304 Same error occurs in other places

tsemachh avatar Jun 19 '25 11:06 tsemachh

I think this is a new error (@firatciftci and @tsemachh and also me 😀 are having) It seems to have started with version 0.43.0. Downgrading to 0.42.0 fixes it for me. I also tested 0.39.0-0.42.0 no issues there as well.

EDIT: a new issue has been added: https://github.com/payloadcms/payload/issues/12876

thopedam avatar Jun 19 '25 19:06 thopedam

@firatciftci #12927 should fix the problem.

kendelljoseph avatar Jun 25 '25 20:06 kendelljoseph

Just want to share based on our setup in above comment after upgrading to v3.46.0:

Production setup:

  1. Behind nginx
  2. Self-host on Openshift cluster
  3. Payloadcms container is served on port 3000

The pasteURL that didn't worked:

allowList: [
    {
      hostname: "my-internal-openshift-pod-svc-name.my-namespace", # Openshift service name
      port: "80", # node port
      protocol: 'http',
    },
  ]

The pasteURL that finally worked:

allowList: [
    {
      hostname: "localhost",
      port: "3000",
      protocol: 'http',
    },
  ]

Openshift service name as hostname will not work because safeFetch() will attempt to do a DNS lookup and disallow private IP address. Which I think is a bug on Payloadcms side cc @kendelljoseph @DanRibbens

https://github.com/payloadcms/payload/blob/v3.46.0/packages/payload/src/uploads/safeFetch.ts#L20

const isSafeIp = (ip: string) => {
  try {
    ...
    if (range !== 'unicast') {
      return false // Private IP Range
    }
   ...
}

Related to #13146

greenlover1991 avatar Aug 13 '25 06:08 greenlover1991