{"record":{"id":"41e9d191154f8903","repo":"istio/istio","slug":"polldelay-must-be-non-zero","errorCode":null,"errorMessage":"pollDelay must be non zero","messagePattern":"pollDelay must be non zero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/validation/agent/validation.go","lineNumber":484,"sourceCode":"}\n\nfunc validatePrivateKeyProvider(pkpConf *meshconfig.PrivateKeyProvider) error {\n\tvar errs error\n\tif pkpConf.GetProvider() == nil {\n\t\terrs = multierror.Append(errs, errors.New(\"private key provider configuration is required\"))\n\t}\n\n\tswitch pkpConf.GetProvider().(type) {\n\tcase *meshconfig.PrivateKeyProvider_Cryptomb:\n\t\tcryptomb := pkpConf.GetCryptomb()\n\t\tif cryptomb == nil {\n\t\t\terrs = multierror.Append(errs, errors.New(\"cryptomb configuration is required\"))\n\t\t} else {\n\t\t\tpollDelay := cryptomb.GetPollDelay()\n\t\t\tif pollDelay == nil {\n\t\t\t\terrs = multierror.Append(errs, errors.New(\"pollDelay is required\"))\n\t\t\t} else if pollDelay.GetSeconds() == 0 && pollDelay.GetNanos() == 0 {\n\t\t\t\terrs = multierror.Append(errs, errors.New(\"pollDelay must be non zero\"))\n\t\t\t}\n\t\t}\n\tcase *meshconfig.PrivateKeyProvider_Qat:\n\t\tqatConf := pkpConf.GetQat()\n\t\tif qatConf == nil {\n\t\t\terrs = multierror.Append(errs, errors.New(\"qat configuration is required\"))\n\t\t} else {\n\t\t\tpollDelay := qatConf.GetPollDelay()\n\t\t\tif pollDelay == nil {\n\t\t\t\terrs = multierror.Append(errs, errors.New(\"pollDelay is required\"))\n\t\t\t} else if pollDelay.GetSeconds() == 0 && pollDelay.GetNanos() == 0 {\n\t\t\t\terrs = multierror.Append(errs, errors.New(\"pollDelay must be non zero\"))\n\t\t\t}\n\t\t}\n\tdefault:\n\t\terrs = multierror.Append(errs, errors.New(\"unknown private key provider\"))\n\t}\n","sourceCodeStart":466,"sourceCodeEnd":502,"githubUrl":"https://github.com/istio/istio/blob/8dc789c5cf17517c64e3c36cb3288230f149dfae/pkg/config/validation/agent/validation.go#L466-L502","documentation":"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.","triggerScenarios":"`privateKeyProvider: {cryptomb: {pollDelay: 0s}}` (or a durationpb with Seconds==0 && Nanos==0) reaching ValidateMeshConfigProxyConfig.","commonSituations":"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.","solutions":["Set pollDelay to a positive duration such as `5s` (or `500ms` if you need tighter latency).","If a template renders the value, guard it so an unset variable does not default to 0.","Note both sub-second (nanos) and seconds components are checked — `0s` fails, `100ms` passes."],"exampleFix":"# before\ndefaultConfig:\n  privateKeyProvider:\n    cryptomb:\n      pollDelay: 0s\n\n# after\ndefaultConfig:\n  privateKeyProvider:\n    cryptomb:\n      pollDelay: 5s","handlingStrategy":"validation","validationCode":"if d := pkp.GetCryptomb().GetPollDelay(); d != nil && d.GetSeconds() == 0 && d.GetNanos() == 0 {\n    return fmt.Errorf(\"cryptomb.pollDelay must be > 0\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp rendered pollDelay to a minimum (e.g. 1ms) in templates.","Remember 0 is not a valid 'fastest' setting here — it is rejected."],"tags":["istio","mesh-config","private-key-provider","cryptomb","poll-delay","validation","go"],"backgroundTag":null,"analyzedSha":"8dc789c5cf17517c64e3c36cb3288230f149dfae","analyzedAt":"2026-08-15T15:16:55.434Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}