argoproj/argo-workflows · error
secure must be set if EncryptOpts.SSECPassword is set
Error message
secure must be set if EncryptOpts.SSECPassword is set
What it means
NewClient requires TLS (Secure) when an SSEC customer-key password is configured, because the SSE-C key must never travel over an unencrypted connection. Client construction fails outright when ServerSideCustomerKey is set but opts.Secure is false.
Source
Thrown at workflow/artifacts/s3/s3.go:529
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)
var nbThreads int
if nbThreadsStr != "" {
var err error
logging.RequireLoggerFromContext(s.ctx).WithFields(logging.Fields{"envvar": common.EnvVarS3UploadThreads, "nbThreads": nbThreadsStr}).Info(s.ctx, "Number of threads or s3 multipart upload detected")View on GitHub (pinned to 35bff19146)
Solutions
- Set secure: true (insecure: false) in the S3 artifact config, ensuring the endpoint serves TLS
- Or remove the ssecPassword option if you don't actually need SSE-C
- Configure TLS on your Minio/S3 endpoint (MINIO_* certs or a TLS-terminating proxy) before enabling SSE-C
Example fix
// before
s3:
endpoint: minio:9000
insecure: true
encryptionOptions:
ssecPasswordSecret: {name: ssec, key: pw}
// after
s3:
endpoint: minio:9000
insecure: false
encryptionOptions:
ssecPasswordSecret: {name: ssec, key: pw} Defensive patterns
Strategy: validation
Validate before calling
func validateSSEC(o s3.Opts) error {
if o.EncryptOpts.ServerSideCustomerKey != "" && !o.Secure {
return errors.New("SSEC requires secure=true (TLS)")
}
return nil
} Type guard
func ssecWithoutTLS(o s3.Opts) bool {
return o.EncryptOpts.ServerSideCustomerKey != "" && !o.Secure
} Prevention
- Never combine insecure: true with ssecPassword
- Verify the Minio/S3 endpoint presents a valid TLS cert before enabling SSE-C
- Use https endpoints in prod; reserve insecure for local non-SSEC dev
When it happens
Trigger: encryptionOptions.ssecPassword set while the S3 config has insecure: true (or the endpoint scheme is http), e.g. against a local Minio without TLS.
Common situations: Local Minio dev setups with insecure: true plus copied production encryption settings; users assuming SSE-C works over plain HTTP; missing enableTLS on Minio gateway.
Related errors
- serverSideCustomerKeySecret and kmsKeyId cannot be set toget
- EncryptOpts.KmsKeyId and EncryptOpts.SSECPassword cannot be
- failed to parse KMS encryption context: %w
- failure to create dynamic client: %w
- failed to append certificates from PEM string
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/ab3a488a53b004cf.
Report an issue: GitHub.