Slack files.completeUploadExternal sometimes fails with internal_error:put, internal_error:resp, or CloudFront 504 – what could cause this?

Slack has deprecated the files.upload API, so I’m migrating to the recommended flow using files.getUploadURLExternal → direct file upload → files.completeUploadExternal

Most of the time this flow works, but intermittently it fails with the following errors:
• “error”: “internal_error:put”
• “error”: “internal_error:resp”
• HTTP 504 Gateway Timeout from CloudFront during the direct file upload step.

I can’t yet determine what triggers the failures — file size seems small (~30KB), and the behavior is inconsistent.

Here’s a simplified version of my PHP (Symfony) flow:

  1. Get Upload URL

    $getUrlResponse = $this->slackApi->request('POST', 'https://slack.com/api/files.getUploadURLExternal', [
             'body' => [
                 'filename' => 'Purchase Order 204.pdf',
                 'length' => 31112,
             ],
         ]);
    
  2. Upload the file:

    $uploadResponse = $this->slackApi->request('POST', $getUrlResponse->getUploadUrl(), [
        'body' => $parameters->getFile(), // Raw binary stream
    ]);
    
    if ($uploadResponse->getStatusCode() !== 200) {
        throw new LogicException($uploadResponse->getContent(false));
    }
  1. Complete the upload:
    $this->slackApi->request('POST', 'https://slack.com/api/files.completeUploadExternal', [
        'json' => [
            'files' => [[
                'id' => $getUrlResponse->getFileId(),
                'title' => $parameters->getFilename(),
            ]],
            'channel_id' => $parameters->getChannelId(),
            'thread_ts' => $parameters->getThreadTs(),
        ],
    ]);
    ```


Are there known reasons behind internal_error:put or CloudFront 504 in this flow, and how can they be mitigated?