temporalio/temporal · critical
Elasticsearch processor is nil
Error message
Elasticsearch processor is nil
What it means
VisibilityStore.checkProcessor panics when the Elasticsearch visibility store's background indexer (processor) is nil. The processor is the async bulk-indexing pipeline created during store initialization (wired up by history service config); AddBulkRequestAndWait calls checkProcessor before use, and a nil processor means the store was constructed without the required ES indexing machinery — commented in source as 'must be a bug, check history setup'.
Source
Thrown at common/persistence/visibility/store/elasticsearch/visibility_store.go:372
}
// Returns non-retryable Internal error here because these errors are unexpected.
// Visibility task processor retries all errors though; therefore, new request will be generated for the same visibility task.
return serviceerror.NewInternalf("visibility task received error: %v", err)
}
if !ack {
// Returns retryable Unavailable error here because NACK from bulk processor
// means that this request wasn't processed successfully and needs to be retried.
// Visibility task processor retries all errors anyway, therefore, new request will be generated for the same visibility task.
return serviceerror.NewUnavailable("visibility task received NACK")
}
return nil
}
func (s *VisibilityStore) checkProcessor() {
if s.processor == nil {
// must be a bug, check history setup
panic("Elasticsearch processor is nil")
}
if s.processorAckTimeout == nil {
// must be a bug, check history setup
panic("config.ESProcessorAckTimeout is nil")
}
}
func (s *VisibilityStore) ListWorkflowExecutions(
ctx context.Context,
request *manager.ListWorkflowExecutionsRequestV2,
) (*store.InternalListExecutionsResponse, error) {
p, err := s.BuildSearchParametersV2(request, s.GetListFieldSorter)
if err != nil {
return nil, err
}
searchResult, err := s.esClient.Search(ctx, p)
if err != nil {View on GitHub (pinned to bde624efd1)
Solutions
- Verify visibility persistence config: ensure the store is truly Elasticsearch and that history service setup creates the processor (esVisibilityStore init in history service bootstrap).
- Use the standard NewVisibilityStore constructor path so processor and processorAckTimeout are always populated; never build the struct literal directly in tests.
- If running non-ES (SQL/Cassandra) visibility, fix the store selection so ES-specific code paths are not invoked.
- Check startup logs/config for earlier processor-creation errors and restart the service after fixing wiring.
Example fix
// before (test/store construction)
store := &elasticsearch.VisibilityStore{ESClient: client, Logger: logger} // processor nil
// after
store := elasticsearch.NewVisibilityStore(client, schema, "index", logger, metricClient, esCfg, esProcessorCfg) // processor created internally Defensive patterns
Strategy: validation
Validate before calling
func (s *VisibilityStore) bulkReady() error {
if s.processor == nil { return errors.New("ES processor not initialized; check history setup") }
if s.processorAckTimeout == nil { return errors.New("ESProcessorAckTimeout not configured") }
return nil
} Type guard
func (s *VisibilityStore) processorReady() bool { return s.processor != nil && s.processorAckTimeout != nil } Try / catch
// panics here are process-fatal; check readiness before bulk writes
if err := store.BulkReady(); err != nil { logger.Error(err.Error()); return err }
return store.AddBulkRequestAndWait(ctx, req) Prevention
- Always construct VisibilityStore via its constructor, never struct literals
- Assert processor initialization during service bootstrap/health checks
- Align visibility store kind with actual backend config (ES vs SQL)
When it happens
Trigger: Calling AddBulkRequestAndWait (directly or via visibility manager write paths) on a VisibilityStore created with a nil processor — e.g. the store was built for a non-ES backend but registered as ES, or the NewVisibilityStore wiring skipped processor creation while config still selected Elasticsearch.
Common situations: Config choosing elasticsearch visibility store but initialization code path failing silently to create the processor; double store instantiation where the processor is attached to a different instance; tests constructing VisibilityStore struct literals without processor; startup ordering bugs in history service setup.
Related errors
- config.ESProcessorAckTimeout is nil
- Unknown field type: %v
- requires a StartTime or CloseTime
- chasm visibilityTaskHandler should not be called directly
- panic(err)
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/479a683bae435625.
Report an issue: GitHub.