nats-io/nats-server · error

invalid mapping destination: not using all of the token wild

Error message

invalid mapping destination: not using all of the token wildcard(s)

What it means

ErrMappingDestinationNotUsingAllWildcards is returned by NewSubjectTransformWithStrict when the destination subject has fewer placeholders than the source subject has wildcards. In strict mode every source wildcard token must be consumed by the destination; otherwise the mapping would silently drop information, so the server rejects it.

Source

Thrown at server/errors.go:232

	// ErrDuplicateServerName is returned when processing a server remote connection and
	// the server reports that this server name is already used in the cluster.
	ErrDuplicateServerName = errors.New("duplicate server name")

	// ErrMinimumVersionRequired is returned when a connection is not at the minimum version required.
	ErrMinimumVersionRequired = errors.New("minimum version required")
	// ErrLeafNodeMinVersionRejected is the leafnode protocol error prefix used
	// when rejecting a remote due to leafnodes.min_version.
	ErrLeafNodeMinVersionRejected = errors.New("connection rejected since minimum version required is")

	// ErrInvalidMappingDestination is used for all subject mapping destination errors
	ErrInvalidMappingDestination = errors.New("invalid mapping destination")

	// ErrInvalidMappingDestinationSubject is used to error on a bad transform destination mapping
	ErrInvalidMappingDestinationSubject = fmt.Errorf("%w: invalid transform", ErrInvalidMappingDestination)

	// ErrMappingDestinationNotUsingAllWildcards is used to error on a transform destination not using all of the token wildcards
	ErrMappingDestinationNotUsingAllWildcards = fmt.Errorf("%w: not using all of the token wildcard(s)", ErrInvalidMappingDestination)

	// ErrUnknownMappingDestinationFunction is returned when a subject mapping destination contains an unknown mustache-escaped mapping function.
	ErrUnknownMappingDestinationFunction = fmt.Errorf("%w: unknown function", ErrInvalidMappingDestination)

	// ErrMappingDestinationIndexOutOfRange is returned when the mapping destination function is passed an out of range wildcard index value for one of it's arguments
	ErrMappingDestinationIndexOutOfRange = fmt.Errorf("%w: wildcard index out of range", ErrInvalidMappingDestination)

	// ErrMappingDestinationNotEnoughArgs is returned when the mapping destination function is not passed enough arguments
	ErrMappingDestinationNotEnoughArgs = fmt.Errorf("%w: not enough arguments passed to the function", ErrInvalidMappingDestination)

	// ErrMappingDestinationInvalidArg is returned when the mapping destination function is passed and invalid argument
	ErrMappingDestinationInvalidArg = fmt.Errorf("%w: function argument is invalid or in the wrong format", ErrInvalidMappingDestination)

	// ErrMappingDestinationTooManyArgs is returned when the mapping destination function is passed too many arguments
	ErrMappingDestinationTooManyArgs = fmt.Errorf("%w: too many arguments passed to the function", ErrInvalidMappingDestination)

	// ErrMappingDestinationNotSupportedForImport is returned when you try to use a mapping function other than wildcard in a transform that needs to be reversible (i.e. an import)
	ErrMappingDestinationNotSupportedForImport = fmt.Errorf("%w: the only mapping function allowed for import transforms is {{Wildcard()}}", ErrInvalidMappingDestination)

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Reference every source wildcard in the destination, in order, via '*' placeholders or transform functions like {{Wildcard(1)}}
  2. If dropping wildcards is intentional, use the non-strict transform constructor (NewSubjectTransform) where allowed
  3. Re-run the transform validation locally on all mapping entries after config changes

Example fix

// before
src := "foo.*.*"
dest := "bar.*" // drops the second wildcard
// after
dest := "bar.*.*" // or "bar.{{Wildcard(1)}}.{{Wildcard(2)}}"
Defensive patterns

Strategy: validation

Validate before calling

srcWildcards := strings.Count(src, "*")
destPlaceholders := countWildcardsOrFuncs(dest)
if destPlaceholders < srcWildcards {
    return fmt.Errorf("dest %q must use all %d wildcards from %q", dest, srcWildcards, src)
}

Type guard

func usesAllWildcards(src, dest string) bool {
    t, err := server.NewSubjectTransformWithStrict(src, dest)
    return err == nil && t != nil
}

Try / catch

if err != nil {
    if errors.Is(err, server.ErrMappingDestinationNotUsingAllWildcards) {
        return fmt.Errorf("mapping drops wildcards: %w", err)
    }
}

Prevention

When it happens

Trigger: NewSubjectTransformWithStrict(source, dest) where the source contains N wildcards but the destination references fewer than N wildcard placeholders (strict mode on). Example: source 'foo.*.*' with destination 'bar.*'.

Common situations: Config `mappings` entries where the destination was hand-written and forgot to reuse a '*' from the source; tightening an existing mapping to strict validation after a server upgrade; JetStream subject transforms that drop wildcard tokens.

Related errors


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