{"record":{"id":"372fbe0a6daa0a78","repo":"payloadcms/payload","slug":"could-not-read-uploaded-file-for-validation","errorCode":null,"errorMessage":"Could not read uploaded file for validation.","messagePattern":"Could not read uploaded file for validation\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"packages/payload/src/uploads/checkFileRestrictions.ts","lineNumber":128,"sourceCode":"  // just for detection. For content validation (SVG safety, PDF integrity), the full buffer is\n  // loaded lazily and only when the file type actually requires it.\n  const { tempFilePath } = file\n  const isTempFile = !!tempFilePath && (!file.data || file.data.length === 0)\n\n  // Lazily reads the full file — only reached for small text-based types (SVG, PDF).\n  let _fileBuffer: Buffer | undefined\n  const getFileBuffer = async (): Promise<Buffer> => {\n    if (_fileBuffer) {\n      return _fileBuffer\n    }\n    if (!isTempFile || !tempFilePath) {\n      return (_fileBuffer = file.data)\n    }\n    try {\n      _fileBuffer = await fs.readFile(tempFilePath)\n      return _fileBuffer\n    } catch {\n      throw new ValidationError({\n        errors: [{ message: 'Could not read uploaded file for validation.', path: 'file' }],\n      })\n    }\n  }\n\n  // Secondary mimetype check to assess file type from buffer\n  if (configMimeTypes.length > 0) {\n    let detected\n    try {\n      detected =\n        isTempFile && tempFilePath\n          ? await fileTypeFromFile(tempFilePath)\n          : await fileTypeFromBuffer(file.data)\n    } catch {\n      throw new ValidationError({\n        errors: [{ message: 'Could not read uploaded file for type detection.', path: 'file' }],\n      })\n    }","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/uploads/checkFileRestrictions.ts#L110-L146","documentation":"Thrown when the lazy getFileBuffer() helper cannot read the temp file from disk via fs.readFile during content-level validation (SVG safety, PDF integrity). This path is only reached for temp-file uploads (large files written to disk by the multipart parser) whose buffer is empty, and only when the file's detected/extension type requires reading contents.","triggerScenarios":"A large uploaded file was written to a temp path, then that temp file was deleted, moved, or made unreadable (permissions, container volume unmount) between multipart parse and the content-validation step. Also reachable if tempFilePath points to a non-existent path due to a custom upload adapter or a tmp cleanup job.","commonSituations":"OS temp directory cleanup (systemd-tmpfiles, cron) running mid-request; Docker/k8s restarting and wiping the tmpfs; reverse proxy or middleware stripping the temp file; misconfigured upload.adapater setting an invalid tempFilePath; concurrent request or cleanup hook removing the temp file.","solutions":["Ensure the OS temp directory is not garbage-collected during the request lifecycle (raise TMPFILES age / disable cron cleanup of the upload temp dir).","Confirm tempFilePath on the file object resolves to an existing, readable file before checkFileRestrictions runs.","If using a custom storage adapter, verify it writes temp files to a stable, process-accessible location.","Handle the ValidationError in the upload route and surface a retry prompt to the user."],"exampleFix":"// before — temp file may vanish before validation\nawait checkFileRestrictions({ checkFileContents: true, collection, file, req })\n// after — guard reads and retry on transient FS errors\nimport { existsSync } from 'fs'\nif (file.tempFilePath && !existsSync(file.tempFilePath)) {\n  throw new Error('Temp file vanished; please re-upload.')\n}\nawait checkFileRestrictions({ checkFileContents: true, collection, file, req })","handlingStrategy":"try-catch","validationCode":"import { existsSync, accessSync, constants } from 'fs'\nfunction tempFileReadable(p?: string): boolean {\n  if (!p) return true // in-memory upload, not applicable\n  try { accessSync(p, constants.R_OK); return existsSync(p) } catch { return false }\n}\n// before upload pipeline:\nif (file.tempFilePath && !tempFileReadable(file.tempFilePath)) throw new Error('Temp file unreadable')","typeGuard":"const hasReadableTempFile = (f: { tempFilePath?: string }): boolean =>\n  !f.tempFilePath || (f.tempFilePath.length > 0)","tryCatchPattern":"try {\n  await payload.create({ collection: 'media', file })\n} catch (e) {\n  if (e instanceof ValidationError && /Could not read uploaded file/.test(e.message)) {\n    askUserToRetry('Temporary file could not be read. Please re-upload.')\n  } else throw e\n}","preventionTips":["Don't run tmp-cleanup cron on the upload temp dir during request handling.","Monitor disk space on the temp volume.","Use the same uid:gid for the uploader and the validator process.","If on k8s, use an emptyDir that lives for the pod, not a node-level tmp."],"tags":["upload","filesystem","temp-file","validation"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}