jaegertracing/jaeger · error

unrecognized write_mode %q: valid values are %q and %q

Error message

unrecognized write_mode %q: valid values are %q and %q

What it means

Jaeger's Elasticsearch storage config validates the optional write_mode setting before creating a client. write_mode accepts only an empty value (default), 'async', or 'sync'; any other string is rejected at config-validation time with this error rather than silently falling back. This prevents typos like 'asynchronous' from producing unexpected indexing behavior.

Source

Thrown at internal/storage/elasticsearch/config/config.go:562

func validatePoisonHandling(mode PoisonHandling) error {
	switch mode {
	case "", PoisonFail, PoisonDrop:
		return nil
	default:
		return fmt.Errorf("unrecognized poison_pill_handling %q: valid values are %q and %q", mode, PoisonFail, PoisonDrop)
	}
}

// validateWriteMode rejects an unrecognized write_mode. An empty value is allowed
// and resolves to the default (WriteModeAsync). It mirrors validateLogLevel:
// write_mode carries no govalidator struct tag, so the whole-config Validate must
// check it explicitly.
func validateWriteMode(mode WriteMode) error {
	switch mode {
	case "", WriteModeAsync, WriteModeSync:
		return nil
	default:
		return fmt.Errorf("unrecognized write_mode %q: valid values are %q and %q", mode, WriteModeAsync, WriteModeSync)
	}
}

// validateLogLevel rejects an unrecognized log_level. An empty value is allowed
// and means no client logging is attached.
func validateLogLevel(level string) error {
	switch level {
	case "", "debug", "info", "error":
		return nil
	default:
		return fmt.Errorf("unrecognized log_level %q: valid values are debug, info, error", level)
	}
}

// rejectUnwiredKey builds the validation error for a config key that the current
// Elasticsearch client no longer reads, pointing operators at the PR that explains
// the change. The migration is always the same: remove the key.
func rejectUnwiredKey(key, reason string) error {

View on GitHub (pinned to 806f444784)

Solutions

  1. Set write_mode to one of: (empty), 'async', or 'sync'
  2. Remove the write_mode key entirely to use the default
  3. Check for stray whitespace/case in the value (it is matched exactly against lowercase literals)

Example fix

// before
write_mode: asynchronous
// after
write_mode: async
Defensive patterns

Strategy: validation

Validate before calling

validWriteModes := map[string]bool{"": true, "async": true, "sync": true}
if !validWriteModes[cfg.WriteMode] {
    return fmt.Errorf("write_mode must be one of: (empty), async, sync; got %q", cfg.WriteMode)
}

Prevention

When it happens

Trigger: Setting es.write_mode (or the WriteMode field in config.Config) to any value other than '', 'async', or 'sync' and calling Validate on the config.

Common situations: Typo in YAML such as write_mode: Async or write_mode: bulk; copying config from old Jaeger docs that used different values; environment variable ES_WRITE_MODE set with an invalid value.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/f683158d6db34eb6. Report an issue: GitHub.