# Custom headers not being passed from AwsS3 plugin to Companion

**URL:** <https://community.transloadit.com/t/custom-headers-not-being-passed-from-awss3-plugin-to-companion/17630>\
**Category:** Uppy\
**Created:** [June 3, 2025, 9:34pm UTC](https://community.transloadit.com/t/custom-headers-not-being-passed-from-awss3-plugin-to-companion/17630 "2025-06-03T21:34:25Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![collie.masque](https://avatars.discourse-cdn.com/v4/letter/c/7bcc69/32.png) [@collie.masque](https://community.transloadit.com/u/collie.masque)\
**Post date:** [June 3, 2025, 9:34pm UTC](https://community.transloadit.com/t/custom-headers-not-being-passed-from-awss3-plugin-to-companion/17630/1 "2025-06-03T21:34:25Z")

</div>

Hello Uppy team,

I’m experiencing an issue where custom headers specified in the AwsS3 plugin are not being passed to my Companion server. I’ve tried multiple approaches based on various GitHub issues and forum posts, but none have worked.

**Environment**

- Uppy version: 4.17.0 (CDN)
- Companion version: 5.8.0
- Node.js: 18.20.8
- Deployment: Companion running on separate subdomain

**What I’m trying to achieve**

I need to pass user-specific information (x-user-id and x-database-id)  
from the client to Companion so I can organize S3 uploads in  
user-specific folders using a custom getKey function.

**Current Setup**

**Client-side (Uppy configuration):**

```auto
  const { Uppy, Dashboard, AwsS3, OneDrive, GoogleDrive } = window.Uppy;

  const uppy = new Uppy({
    debug: true,
    // ... other config
  });

  // Tried setting metadata
  uppy.setMeta({
    userId: '{{ request.user.id }}',
    databaseId: '{{ database.index }}'
  });

  // Tried multiple header configurations
  uppy.use(AwsS3, {
    endpoint: 'https://uploads.domain.com',
    headers: { // Also tried 'companionHeaders'
      'x-requested-with': 'XMLHttpRequest',
      'x-user-id': '{{ request.user.id }}',
      'x-database-id': '{{ database.index }}'
    }
  });

```

**Server-side (Companion configuration):**

```auto
  const app = express();

  // Added custom CORS middleware before Companion
  app.use((req, res, next) => {
    res.header('Access-Control-Allow-Headers',
      'Authorization, Origin, Content-Type, Accept, uppy-auth-token, 
  uppy-versions, x-user-id, x-database-id, x-requested-with'
    );
    res.header('Access-Control-Expose-Headers',
  'Access-Control-Allow-Headers');

    if (req.method === 'OPTIONS') {
      res.header('Access-Control-Allow-Origin', req.headers.origin ||
  '*');
      res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, 
  PUT, PATCH, DELETE');
      res.header('Access-Control-Allow-Credentials', 'true');
      return res.sendStatus(200);
    }

    next();
  });

  const companionOptions = {
    corsOrigins: true,
    s3: {
      key: process.env.COMPANION_AWS_KEY,
      secret: process.env.COMPANION_AWS_SECRET,
      bucket: process.env.COMPANION_AWS_BUCKET,
      region: process.env.COMPANION_AWS_REGION || 'us-east-1',
      getKey: (req, filename, metadata) => {
        // Trying to get data from both metadata and headers
        let userId = metadata?.userId || req.headers['x-user-id'] ||
  'anonymous';
        let databaseId = metadata?.databaseId ||
  req.headers['x-database-id'] || 'default';

        const key = `${userId}/${databaseId}/raw/${filename}`;

        console.log('Generating S3 key:', {
          userId, databaseId, filename, key,
          metadata, headers: req.headers
        });

        return key;
      }
    },
    // ... other config
  };

```

**What I’ve tried**

1. Using headers property in AwsS3 plugin configuration
2. Using companionHeaders property (found in some GitHub issues)
3. Setting metadata with uppy.setMeta()
4. Adding custom CORS middleware before Companion
5. Exposing Access-Control-Allow-Headers in CORS response
6. Using lowercase header names (Node.js normalization)
7. Trying AwsS3Multipart instead of AwsS3

The Problem  
**strong text**  
When I log the incoming requests in Companion:

- The custom headers (x-user-id, x-database-id) are not present in  
req.headers
- The metadata object in getKey is either undefined or doesn’t contain  
my custom fields
- Files are always uploaded to the anonymous/default/raw/ path

**Debug Output**

From my debug middleware, I can see Uppy IS sending the standard  
headers, but my custom headers are missing:  
=== Incoming Request ===  
Method: POST  
URL: /s3/params  
Headers: {  
“host”: “[uploads.domain.com](http://uploads.domain.com)”,  
“content-type”: “application/json”,  
“accept”: “application/json”,  
“uppy-versions”: “@uppy/aws-s3=…”,  
// … other standard headers  
// But NO x-user-id or x-database-id!  
}

What is the correct way to pass custom headers from the AwsS3 plugin to Companion in the latest versions?

I’ve seen various GitHub issues (#[2465](https://github.com/transloadit/uppy/issues/2465), #[1059](https://github.com/transloadit/uppy/issues/1059), #[2089](https://github.com/transloadit/uppy/issues/2089)) mentioning  
similar problems, but the solutions don’t seem to work with the current  
versions.

Any help would be greatly appreciated! This is blocking our ability to  
properly organize user uploads in S3.

Thank you!
