nats-io/nats-server · error

expected 'no_extend' for string value, got '%s'

Error message

expected 'no_extend' for string value, got '%s'

What it means

The `jetstream.extend_write` (JetStreamExtHint) option accepts only the literal strings 'extend' (jsWillExtend), 'no_extend', or an empty value; anything else after lowercasing is rejected at validation. This hint tells the server how external (non-NATS) writers to mirrored/direct streams should behave.

Source

Thrown at server/jetstream.go:2952

		}
	}
	// If not clustered no checks needed past here.
	if !o.JetStream || o.Cluster.Port == 0 {
		return nil
	}
	if o.ServerName == _EMPTY_ {
		return fmt.Errorf("jetstream cluster requires `server_name` to be set")
	}
	if o.Cluster.Name == _EMPTY_ {
		return fmt.Errorf("jetstream cluster requires `cluster.name` to be set")
	}

	h := strings.ToLower(o.JetStreamExtHint)
	switch h {
	case jsWillExtend, jsNoExtend, _EMPTY_:
		o.JetStreamExtHint = h
	default:
		return fmt.Errorf("expected 'no_extend' for string value, got '%s'", h)
	}

	if o.JetStreamMaxCatchup < 0 {
		return fmt.Errorf("jetstream max catchup cannot be negative")
	}
	return nil
}

// We had a bug that set a default de dupe window on mirror, despite that being not a valid config
func fixCfgMirrorWithDedupWindow(cfg *StreamConfig) {
	if cfg == nil || cfg.Mirror == nil {
		return
	}
	if cfg.Duplicates != 0 {
		cfg.Duplicates = 0
	}
}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Change the value to exactly `no_extend` if you want external writes not to extend, or `extend` if they should.
  2. Remove the option entirely (empty value is allowed) to use the default behavior.
  3. Restart the server to re-validate.

Example fix

// before
jetstream: { extend_write: "disabled" }
// after
jetstream: { extend_write: "no_extend" }
Defensive patterns

Strategy: validation

Validate before calling

v := strings.ToLower(cfg.JetStream.ExtendWrite)
switch v {
case "", "extend", "no_extend":
    // ok
default:
    return fmt.Errorf("extend_write must be 'extend' or 'no_extend', got %q", v)
}

Prevention

When it happens

Trigger: Setting jetstream extend_write to any string other than "extend", "no_extend", or "" — e.g. a misspelled value, wrong casing handled incorrectly, or a boolean/numeric value serialized as an unexpected string.

Common situations: Typo like "no-extent" or "noextend"; config tooling writing "true"/"false" into a string-only enum option; upgrading from configs written for a different option shape.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/75e14fae77d42f60. Report an issue: GitHub.