argoproj/argo-workflows · error

invalid maxAge: %w

Error message

invalid maxAge: %w

What it means

When a memoized template's cache entry is considered, executeTemplate parses memoize.maxAge as a Go duration. If the maxAge string in the template spec is not a valid duration (e.g. '1d', '24', 'day'), the controller returns 'invalid maxAge: %w' wrapping the time.ParseDuration error and marks the node as error via initializeNodeOrMarkError before the cache entry is ever consulted.

Source

Thrown at workflow/controller/operator.go:2378

			memoizationCache := woc.controller.cacheFactory.GetCache(controllercache.ConfigMapCache, processedTmpl.Memoize.Cache.ConfigMap.Name)
			if memoizationCache == nil {
				cacheErr := fmt.Errorf("cache could not be found or created")
				woc.log.WithFields(logging.Fields{"cacheName": processedTmpl.Memoize.Cache.ConfigMap.Name}).WithError(cacheErr)
				errNode := woc.initializeNodeOrMarkError(ctx, node, nodeName, templateScope, orgTmpl, opts.boundaryID, opts.nodeFlag, cacheErr)
				return errNode, cacheErr
			}

			entry, loadErr := memoizationCache.Load(ctx, processedTmpl.Memoize.Key)
			if loadErr != nil {
				return woc.initializeNodeOrMarkError(ctx, node, nodeName, templateScope, orgTmpl, opts.boundaryID, opts.nodeFlag, loadErr), loadErr
			}

			hit := entry.Hit()
			var outputs *wfv1.Outputs
			if processedTmpl.Memoize.MaxAge != "" {
				maxAge, parseErr := time.ParseDuration(processedTmpl.Memoize.MaxAge)
				if parseErr != nil {
					maxAgeErr := fmt.Errorf("invalid maxAge: %w", parseErr)
					return woc.initializeNodeOrMarkError(ctx, node, nodeName, templateScope, orgTmpl, opts.boundaryID, opts.nodeFlag, maxAgeErr), maxAgeErr
				}
				maxAgeOutputs, ok := entry.GetOutputsWithMaxAge(maxAge)
				if !ok {
					// The outputs are expired, so this cache entry is not hit
					hit = false
				}
				outputs = maxAgeOutputs
			} else {
				outputs = entry.GetOutputs()
			}

			memoizationStatus := &wfv1.MemoizationStatus{
				Hit:       hit,
				Key:       processedTmpl.Memoize.Key,
				CacheName: processedTmpl.Memoize.Cache.ConfigMap.Name,
			}
			if hit {

View on GitHub (pinned to 35bff19146)

Solutions

  1. Fix memoize.maxAge in the template to a Go duration string with units, e.g. maxAge: "24h" instead of "1d".
  2. Lint the workflow before submitting: argo lint <file> — note older linters may not validate maxAge, so validate durations manually.
  3. If maxAge comes from a ConfigMap/parameter substitution, verify the resolved value with argo submit --dry-run --output json and inspect the memoize block.
  4. Use only units supported by time.ParseDuration: ns, us (µs), ms, s, m, h (compose days as 24h).

Example fix

memoize:
  key: my-cache
# before
  maxAge: "1d"
# after
  maxAge: "24h"
Defensive patterns

Strategy: validation

Validate before calling

// Validate maxAge in your pipeline before applying the manifest
import "time"
func validateMaxAge(s string) error {
	_, err := time.ParseDuration(s)
	return err
}
// usage: validateMaxAge(memoize.MaxAge) must return nil before argo submit

Type guard

func isValidDuration(s string) bool {
	_, err := time.ParseDuration(s)
	return s != "" && err == nil
}

Prevention

When it happens

Trigger: A workflow template with spec.templates[].memoize.maxAge set to a string that time.ParseDuration cannot parse — e.g. missing unit ('30'), unsupported unit ('1d'), or typo ('12hh'). The error is returned by executeTemplate, which is reached via executeDAGTask, hooks, onExit, or normal operate().

Common situations: Users writing human-friendly durations like '1d' or '2w' (Go durations don't support days/weeks); values templated from config that end up empty or malformed; upgrading from a version that never validated maxAge.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


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