argoproj/argo-workflows · error
EncryptOpts.KmsKeyId and EncryptOpts.SSECPassword cannot be
Error message
EncryptOpts.KmsKeyId and EncryptOpts.SSECPassword cannot be set together
What it means
NewClient rejects S3 encryption options that specify both a KMS key ID (SSE-KMS) and an SSEC password (SSE-C), because an object cannot be encrypted with both mechanisms at once. This is a client-construction validation error and is not retriable.
Source
Thrown at workflow/artifacts/s3/s3.go:525
switch s3cli.AddressingStyle {
case PathStyle:
bucketLookupType = minio.BucketLookupPath
case VirtualHostedStyle:
bucketLookupType = minio.BucketLookupDNS
default:
bucketLookupType = minio.BucketLookupAuto
}
minioOpts := &minio.Options{Creds: credentials, Secure: s3cli.Secure, Transport: opts.Transport, Region: s3cli.Region, BucketLookup: bucketLookupType}
minioClient, err = minio.New(s3cli.Endpoint, minioOpts)
if err != nil {
return nil, err
}
if opts.Trace {
minioClient.TraceOn(os.Stderr)
}
if opts.EncryptOpts.KmsKeyID != "" && opts.EncryptOpts.ServerSideCustomerKey != "" {
return nil, fmt.Errorf("EncryptOpts.KmsKeyId and EncryptOpts.SSECPassword cannot be set together")
}
if opts.EncryptOpts.ServerSideCustomerKey != "" && !opts.Secure {
return nil, fmt.Errorf("secure must be set if EncryptOpts.SSECPassword is set")
}
s3cli.ctx = ctx
s3cli.minioClient = minioClient
return &s3cli, nil
}
// Gets number of threads for S3 upload from env var. Default if not set: 4.
func (s *s3client) getFromEnvS3UploadNbThreads() int {
// Minio default threads: https://github.com/minio/minio-go/blob/v7.0.98/constants.go#L58
const defaultThreads = 4
nbThreadsStr := os.Getenv(common.EnvVarS3UploadThreads)View on GitHub (pinned to 35bff19146)
Solutions
- Remove either kmsKeyId or ssecPassword from encryptionOptions, keeping only the mechanism you want
- If you need SSE-KMS, delete the ssecPassword/encryptionKey setting; if SSE-C, drop kmsKeyId and kmsEncryptionContext
- Re-check rendered controller ConfigMap / artifact spec to confirm only one option remains
Example fix
// before
encryptionOptions:
kmsKeyId: alias/aws/s3
ssecPasswordSecret: {name: my-secret, key: password}
// after
encryptionOptions:
kmsKeyId: alias/aws/s3 Defensive patterns
Strategy: validation
Validate before calling
func validateEncOpts(o s3.EncryptOpts) error {
if o.KmsKeyID != "" && o.ServerSideCustomerKey != "" {
return errors.New("set only one of kmsKeyId or ssecPassword")
}
return nil
} Type guard
func hasConflictingEncOpts(o s3.EncryptOpts) bool {
return o.KmsKeyID != "" && o.ServerSideCustomerKey != ""
} Try / catch
if _, err := s3.NewClient(ctx, opts); err != nil && strings.Contains(err.Error(), "cannot be set together") {
// strip one of the encryption options and rebuild
} Prevention
- Keep only one encryption mechanism in encryptionOptions
- Lint rendered controller ConfigMap for stray kms/ssec fields
- Document which mechanism your org uses and template accordingly
When it happens
Trigger: The artifact's S3 encryptionOptions set both kmsKeyId and ssecPassword (via artifact repository config or per-artifact encryptionOptions), then NewClient is invoked.
Common situations: Copying an example config that had one option and adding the other; templating both fields from values files where both secrets happen to be populated; merging operator and user config each contributing a different option.
Related errors
- serverSideCustomerKeySecret and kmsKeyId cannot be set toget
- secure must be set if EncryptOpts.SSECPassword is set
- failed to parse KMS encryption context: %w
- malformed workflow template parameter "%s": valueFrom is nil
- maxRetries cannot be less than 0
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/12dbc7b086a143c5.
Report an issue: GitHub.