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

  1. Set secure: true (insecure: false) in the S3 artifact config, ensuring the endpoint serves TLS
  2. Or remove the ssecPassword option if you don't actually need SSE-C
  3. 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

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


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