{"record":{"id":"769532c0d5172eac","repo":"transloadit/uppy","slug":"the-s3-client-is-not-configured-on-this-companion","errorCode":null,"errorMessage":"The S3 client is not configured on this companion instance.","messagePattern":"The S3 client is not configured on this companion instance\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/@uppy/companion/src/server/Uploader.ts","lineNumber":892,"sourceCode":"            : 'Request failed'\n        throw Object.assign(new Error(statusMessage), {\n          extraData: getRespObj(response as unknown as Response<string>),\n        })\n      }\n\n      throw new Error('Unknown multipart upload error', { cause: err })\n    }\n  }\n\n  /**\n   * Upload the file to S3 using a Multipart upload.\n   */\n  async #uploadS3Multipart(\n    stream: NodeReadableStream,\n    req: Request,\n  ): Promise<UploadResult> {\n    if (!this.options.s3) {\n      throw new Error(\n        'The S3 client is not configured on this companion instance.',\n      )\n    }\n\n    const filename = this.uploadFileName\n    const s3Options = this.options.s3\n    const { metadata } = this\n    const { client, options } = s3Options\n\n    const params: PutObjectCommandInput = {\n      Bucket: getBucket({\n        bucketOrFn: options.bucket,\n        req,\n        metadata,\n        filename,\n      }),\n      Key: options.getKey({ req, filename, metadata }),\n      ContentType: metadata.type,","sourceCodeStart":874,"sourceCodeEnd":910,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/companion/src/server/Uploader.ts#L874-L910","documentation":"#uploadS3Multipart requires server-side S3 credentials. If this.options.s3 is falsy (no S3 client was configured on this Companion instance), it throws 'The S3 client is not configured on this companion instance.' before attempting any AWS calls.","triggerScenarios":"Client requests protocol 's3Multipart' but Companion was started without AWS S3 config (missing AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY or s3 option), so options.s3 is undefined.","commonSituations":"Forgetting to set the four required S3 env vars (key, secret, bucket, region), or expecting the client-side protocol choice alone to enable S3 uploads.","solutions":["Configure S3 on Companion: set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_AWS_BUCKET (bucket), and AWS_REGION env vars, or pass the s3 option programmatically","Restart Companion after adding the variables and confirm they are visible in its environment (e.g. docker-compose env)"],"exampleFix":"# before\ncompainon: # no S3 vars -> error on s3Multipart uploads\n\n# after (docker-compose)\nenvironment:\n  - AWS_ACCESS_KEY_ID=AKIA...\n  - AWS_SECRET_ACCESS_KEY=...\n  - AWS_AWS_BUCKET=my-bucket\n  - AWS_REGION=us-east-1","handlingStrategy":"validation","validationCode":"const s3Configured = Boolean(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY && process.env.AWS_AWS_BUCKET && process.env.AWS_REGION)\nif (protocol === 's3Multipart' && !s3Configured) throw new Error('S3 not configured on server')","typeGuard":null,"tryCatchPattern":"try { await upload() } catch (err) {\n  if (err.message.includes('S3 client is not configured')) { /* fall back to multipart protocol with an endpoint */ }\n}","preventionTips":["Set all four AWS env vars on every Companion instance","Add a startup check that logs whether S3 mode is available"],"tags":["companion","s3","configuration","env-var"],"backgroundTag":"missing-s3-credentials","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}