nats-io/nats-server · error

unknown priority policy: %v

Error message

unknown priority policy: %v

What it means

ConsumerConfig.PriorityPolicy is validated when deserializing its JSON representation; only the recognized JSON strings (mapped to PriorityPinnedClient, PriorityPrioritized, PriorityNone) are accepted. Any other string returns this error during unmarshalling.

Source

Thrown at server/consumer.go:308

	case PriorityNone:
		return PriorityNoneJSONBytes, nil
	default:
		return nil, fmt.Errorf("unknown priority policy: %v", pp)
	}
}

func (pp *PriorityPolicy) UnmarshalJSON(data []byte) error {
	switch string(data) {
	case PriorityOverflowJSONString:
		*pp = PriorityOverflow
	case PriorityPinnedClientJSONString:
		*pp = PriorityPinnedClient
	case PriorityPrioritizedJSONString:
		*pp = PriorityPrioritized
	case PriorityNoneJSONString:
		*pp = PriorityNone
	default:
		return fmt.Errorf("unknown priority policy: %v", string(data))
	}
	return nil
}

// DeliverPolicy determines how the consumer should select the first message to deliver.
type DeliverPolicy int

const (
	// DeliverAll will be the default so can be omitted from the request.
	DeliverAll DeliverPolicy = iota
	// DeliverLast will start the consumer with the last sequence received.
	DeliverLast
	// DeliverNew will only deliver new messages that are sent after the consumer is created.
	DeliverNew
	// DeliverByStartSequence will look for a defined starting sequence to start.
	DeliverByStartSequence
	// DeliverByStartTime will select the first messsage with a timestamp >= to StartTime.
	DeliverByStartTime

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Use one of the exact JSON strings accepted by the PriorityPolicy constants (pinned_client / prioritized / none style values defined in server/consumer.go).
  2. Omit priority_policy (defaults to none) if you do not need priority delivery.
  3. Confirm server version support: priority policies are a newer feature; older servers reject newer policy names.

Example fix

// before
{"priority_policy": "pinned"}
// after
{"priority_policy": "pinned_client"}
Defensive patterns

Strategy: validation

Validate before calling

validPolicies := map[string]bool{"pinned_client": true, "prioritized": true, "none": true}
if cfg.PriorityPolicy != "" && !validPolicies[cfg.PriorityPolicy] {
    return fmt.Errorf("invalid priority_policy %q", cfg.PriorityPolicy)
}

Type guard

func isValidPriorityPolicy(s string) bool {
    switch s {
    case "pinned_client", "prioritized", "none":
        return true
    }
    return false
}

Try / catch

_, err := js.AddConsumer(stream, cfg)
if err != nil && strings.Contains(err.Error(), "unknown priority policy") {
    cfg.PriorityPolicy = "" // fall back to default (none)
    return js.AddConsumer(stream, cfg)
}

Prevention

When it happens

Trigger: Consumer config JSON containing "priority_policy": "overflow" or "pinned" or any string not exactly matching the PriorityPinnedClient/Prioritized/None JSON constants, or a non-string value.

Common situations: Copying examples from blog posts or newer client libraries that use different naming; enabling priority policies on a server whose accepted constants differ; typos in terraform/automation templates for JetStream consumers.

Related errors


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