argoproj/argo-workflows · error

serverSideCustomerKeySecret and kmsKeyId cannot be set toget

Error message

serverSideCustomerKeySecret and kmsKeyId cannot be set together

What it means

newDriver validates S3 EncryptionOptions and rejects artifacts that specify both a ServerSideCustomerKeySecret (SSE-C) and a KmsKeyId (SSE-KMS), since AWS S3 allows only one server-side encryption mechanism per request.

Source

Thrown at workflow/artifacts/artifacts.go:72

			secretKeyBytes, err := ri.GetSecret(ctx, art.S3.SecretKeySecret.Name, art.S3.SecretKeySecret.Key)
			if err != nil {
				return nil, err
			}
			secretKey = secretKeyBytes

			if art.S3.SessionTokenSecret != nil && art.S3.SessionTokenSecret.Name != "" {
				sessionTokenBytes, err := ri.GetSecret(ctx, art.S3.SessionTokenSecret.Name, art.S3.SessionTokenSecret.Key)
				if err != nil {
					return nil, err
				}
				sessionToken = sessionTokenBytes
			}
		}

		if art.S3.EncryptionOptions != nil {
			if art.S3.EncryptionOptions.ServerSideCustomerKeySecret != nil {
				if art.S3.EncryptionOptions.KmsKeyId != "" {
					return nil, fmt.Errorf("serverSideCustomerKeySecret and kmsKeyId cannot be set together")
				}

				serverSideCustomerKeyBytes, err := ri.GetSecret(ctx, art.S3.EncryptionOptions.ServerSideCustomerKeySecret.Name, art.S3.EncryptionOptions.ServerSideCustomerKeySecret.Key)
				if err != nil {
					return nil, err
				}
				serverSideCustomerKey = serverSideCustomerKeyBytes
			}

			enableEncryption = art.S3.EncryptionOptions.EnableEncryption
			kmsKeyID = art.S3.EncryptionOptions.KmsKeyId
			kmsEncryptionContext = art.S3.EncryptionOptions.KmsEncryptionContext
		}

		if art.S3.CASecret != nil && art.S3.CASecret.Name != "" {
			caBytes, err := ri.GetSecret(ctx, art.S3.CASecret.Name, art.S3.CASecret.Key)
			if err != nil {
				return nil, err

View on GitHub (pinned to 35bff19146)

Solutions

  1. Remove kmsKeyId from encryptionOptions and keep serverSideCustomerKeySecret if you must use SSE-C.
  2. Remove serverSideCustomerKeySecret and keep kmsKeyId for SSE-KMS.
  3. Make the choice configurable at the config level and only pass one field from workflow templates.

Example fix

// before
s3:
  encryptionOptions:
    kmsKeyId: arn:aws:kms:us-east-1:123:key/abc
    serverSideCustomerKeySecret:
      name: my-secret
      key: sse-key
// after
s3:
  encryptionOptions:
    kmsKeyId: arn:aws:kms:us-east-1:123:key/abc
Defensive patterns

Strategy: validation

Validate before calling

func validateS3Encryption(art *wfv1.Artifact) error {
	if art.S3 != nil && art.S3.EncryptionOptions != nil &&
		art.S3.EncryptionOptions.ServerSideCustomerKeySecret != nil &&
		art.S3.EncryptionOptions.KmsKeyId != "" {
		return fmt.Errorf("set either serverSideCustomerKeySecret or kmsKeyId, not both")
	}
	return nil
}

Try / catch

if err := validateS3Encryption(art); err != nil { return err }
driver, err := artifacts.NewDriver(ctx, art, ri)
if err != nil { return fmt.Errorf("s3 artifact %s: %w", art.Name, err) }

Prevention

When it happens

Trigger: An S3 artifact whose encryptionOptions contains both serverSideCustomerKeySecret and a non-empty kmsKeyId; raised synchronously inside newDriver before any S3 call is made.

Common situations: Merging encryption settings from a corporate artifact-repository configmap (KMS key) with per-workflow artifact overrides (customer key); copy-pasting example YAML that included both fields.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/635a83f11325b258. Report an issue: GitHub.