istio/istio · error

pollDelay must be non zero

Error message

pollDelay must be non zero

What it means

Thrown by validatePrivateKeyProvider for the cryptomb provider when pollDelay is present but its seconds and nanos are both zero (i.e. a zero duration). A zero poll interval would spin the CryptoMB completion loop, so the validator requires an explicitly positive interval.

Source

Thrown at pkg/config/validation/agent/validation.go:484

}

func validatePrivateKeyProvider(pkpConf *meshconfig.PrivateKeyProvider) error {
	var errs error
	if pkpConf.GetProvider() == nil {
		errs = multierror.Append(errs, errors.New("private key provider configuration is required"))
	}

	switch pkpConf.GetProvider().(type) {
	case *meshconfig.PrivateKeyProvider_Cryptomb:
		cryptomb := pkpConf.GetCryptomb()
		if cryptomb == nil {
			errs = multierror.Append(errs, errors.New("cryptomb configuration is required"))
		} else {
			pollDelay := cryptomb.GetPollDelay()
			if pollDelay == nil {
				errs = multierror.Append(errs, errors.New("pollDelay is required"))
			} else if pollDelay.GetSeconds() == 0 && pollDelay.GetNanos() == 0 {
				errs = multierror.Append(errs, errors.New("pollDelay must be non zero"))
			}
		}
	case *meshconfig.PrivateKeyProvider_Qat:
		qatConf := pkpConf.GetQat()
		if qatConf == nil {
			errs = multierror.Append(errs, errors.New("qat configuration is required"))
		} else {
			pollDelay := qatConf.GetPollDelay()
			if pollDelay == nil {
				errs = multierror.Append(errs, errors.New("pollDelay is required"))
			} else if pollDelay.GetSeconds() == 0 && pollDelay.GetNanos() == 0 {
				errs = multierror.Append(errs, errors.New("pollDelay must be non zero"))
			}
		}
	default:
		errs = multierror.Append(errs, errors.New("unknown private key provider"))
	}

View on GitHub (pinned to 8dc789c5cf)

Solutions

  1. Set pollDelay to a positive duration such as `5s` (or `500ms` if you need tighter latency).
  2. If a template renders the value, guard it so an unset variable does not default to 0.
  3. Note both sub-second (nanos) and seconds components are checked — `0s` fails, `100ms` passes.

Example fix

# before
defaultConfig:
  privateKeyProvider:
    cryptomb:
      pollDelay: 0s

# after
defaultConfig:
  privateKeyProvider:
    cryptomb:
      pollDelay: 5s
Defensive patterns

Strategy: validation

Validate before calling

if d := pkp.GetCryptomb().GetPollDelay(); d != nil && d.GetSeconds() == 0 && d.GetNanos() == 0 {
    return fmt.Errorf("cryptomb.pollDelay must be > 0")
}

Prevention

When it happens

Trigger: `privateKeyProvider: {cryptomb: {pollDelay: 0s}}` (or a durationpb with Seconds==0 && Nanos==0) reaching ValidateMeshConfigProxyConfig.

Common situations: Copy-paste defaults like `pollDelay: 0` intending 'fastest polling'; templating that renders an unset integer as 0; YAML unmarshalling a bare `0` into a duration message.

Related errors


AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15). Data as JSON: /api/errors/41e9d191154f8903. Report an issue: GitHub.