nats-io/nats-server · error · JSStreamInvalidConfigError

invalid compression

Error message

invalid compression

What it means

cfg.Compression (Compression enum: None or S2) failed to marshal to JSON, meaning it is not a recognized compression algorithm value. The server rejects the config with 'invalid compression'. Compression support also requires a sufficiently new server (2.10+).

Source

Thrown at server/stream.go:1900

	var metadataLen int
	for k, v := range config.Metadata {
		metadataLen += len(k) + len(v)
	}
	if metadataLen > JSMaxMetadataLen {
		return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("stream metadata exceeds maximum size of %d bytes", JSMaxMetadataLen))
	}

	cfg := *config

	if _, err := cfg.Retention.MarshalJSON(); err != nil {
		return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid retention"))
	}
	if _, err := cfg.Discard.MarshalJSON(); err != nil {
		return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid discard policy"))
	}
	if _, err := cfg.Compression.MarshalJSON(); err != nil {
		return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid compression"))
	}

	// Make file the default.
	if cfg.Storage == 0 {
		cfg.Storage = FileStorage
	}
	if _, err := cfg.Storage.MarshalJSON(); err != nil {
		return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("invalid storage type"))
	}

	if cfg.Replicas == 0 {
		cfg.Replicas = 1
	}
	if cfg.Replicas > StreamMaxReplicas {
		return cfg, NewJSStreamInvalidConfigError(fmt.Errorf("maximum replicas is %d", StreamMaxReplicas))
	}
	if cfg.Replicas < 0 {
		return cfg, NewJSReplicasCountCannotBeNegativeError()

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Set Compression to jetstream.NoCompression or jetstream.S2Compression explicitly.
  2. Omit the field if you don't need compression.
  3. Confirm the server is >=2.10 before enabling S2 compression.
  4. Validate the enum value numerically before building the config.

Example fix

// before
cfg := jetstream.StreamConfig{Name: "ORDERS", Compression: jetstream.Compression(9)}
// after
cfg := jetstream.StreamConfig{Name: "ORDERS", Compression: jetstream.S2Compression}
Defensive patterns

Strategy: validation

Validate before calling

func validCompression(c jetstream.Compression) error {
  switch c {
  case jetstream.NoCompression, jetstream.S2Compression:
    return nil
  }
  return fmt.Errorf("invalid compression: %d", int(c))
}

Type guard

func isKnownCompression(c jetstream.Compression) bool {
  return c == jetstream.NoCompression || c == jetstream.S2Compression
}

Prevention

When it happens

Trigger: Passing an out-of-range Compression value (e.g. Compression(9)); a zero-value struct field where 0 is not a valid enum member; sending an older client's compression value to a server or vice versa.

Common situations: Upgrading clients across NATS versions where compression constants changed; enabling S2 compression against an older server that doesn't know the field; hand-rolled config structs with wrong numeric values.

Related errors


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