argoproj/argo-workflows · error

failed to parse KMS encryption context: %w

Error message

failed to parse KMS encryption context: %w

What it means

When building SSE-KMS encryption, the kmsEncryptionContext string is parsed as JSON; a parse failure is wrapped with this message and fails client construction. The encryption context must be a valid JSON object (it is later base64-encoded for Minio).

Source

Thrown at workflow/artifacts/s3/s3.go:921

	return err
}

// buildServerSideEnc creates the minio encryption options when putting encrypted items in a bucket
func (e *EncryptOpts) buildServerSideEnc(bucket, key string) (encrypt.ServerSide, error) {
	if e == nil || !e.Enabled {
		return nil, nil
	}

	if e.ServerSideCustomerKey != "" {
		encryption := encrypt.DefaultPBKDF([]byte(e.ServerSideCustomerKey), []byte(bucket+key))

		return encryption, nil
	}

	if e.KmsKeyID != "" {
		encryptionCtx, err := parseKMSEncCntx(e.KmsEncryptionContext)
		if err != nil {
			return nil, fmt.Errorf("failed to parse KMS encryption context: %w", err)
		}

		if encryptionCtx == nil {
			// To overcome a limitation in Minio which checks interface{} == nil.
			kms, kmsErr := encrypt.NewSSEKMS(e.KmsKeyID, nil)
			if kmsErr != nil {
				return nil, kmsErr
			}

			return kms, nil
		}

		kms, err := encrypt.NewSSEKMS(e.KmsKeyID, encryptionCtx)
		if err != nil {
			return nil, err
		}

		return kms, nil

View on GitHub (pinned to 35bff19146)

Solutions

  1. Set kmsEncryptionContext to a valid JSON object string, e.g. '{"key":"value"}'
  2. Quote the value carefully in YAML/Helm so braces and quotes survive templating
  3. Validate with jq: echo '<context>' | jq . must succeed
  4. If no context is needed, omit kmsEncryptionContext entirely (nil context is allowed)

Example fix

// before
kmsEncryptionContext: department=finance
// after
kmsEncryptionContext: '{"department":"finance"}'
Defensive patterns

Strategy: validation

Validate before calling

func validKMSContext(s string) bool {
  if s == "" { return true }
  var m map[string]interface{}
  return json.Unmarshal([]byte(s), &m) == nil
}
// use: if !validKMSContext(cfg.EncryptionOptions.KmsEncryptionContext) { reject }

Type guard

func isJSONObject(s string) bool {
  var v map[string]any
  return json.Unmarshal([]byte(s), &v) == nil
}

Try / catch

if _, err := buildEncryptOpt(e); err != nil && strings.Contains(err.Error(), "parse KMS encryption context") {
  return fmt.Errorf("fix kmsEncryptionContext JSON: %w", err)
}

Prevention

When it happens

Trigger: Artifact S3 encryptionOptions specify kmsEncryptionContext that is not valid JSON (e.g. raw 'foo=bar', trailing comma, single quotes), and KmsKeyID is set so parseKMSEncCntx runs.

Common situations: YAML string values with quotes stripped by templating; users writing k=v style context instead of JSON; Helm values interpolation mangling braces.

Understand the failure class

Related errors


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