nats-io/nats-server · error

expected 'cert_match_by' to be a valid non-empty string

Error message

expected 'cert_match_by' to be a valid non-empty string

What it means

ErrBadCertMatchByField is a config-validation error raised when the cert_match_by option is not a string or is empty. cert_match_by selects how cert_match is interpreted (e.g. thumbprint vs subject), so it must be a valid non-empty string.

Source

Thrown at server/certstore/errors.go:66

	ErrFailedCertSearch = errors.New("unable to find certificate in store")

	// ErrFailedX509Extract represents not being able to extract x509 certificate from found cert in store
	ErrFailedX509Extract = errors.New("unable to extract x509 from certificate")

	// ErrBadMatchByType represents unknown CERT_MATCH_BY passed
	ErrBadMatchByType = errors.New("cert match by type not implemented")

	// ErrBadCertStore represents unknown CERT_STORE passed
	ErrBadCertStore = errors.New("cert store type not implemented")

	// ErrConflictCertFileAndStore represents ambiguous configuration of both file and store
	ErrConflictCertFileAndStore = errors.New("'cert_file' and 'cert_store' may not both be configured")

	// ErrBadCertStoreField represents malformed cert_store option
	ErrBadCertStoreField = errors.New("expected 'cert_store' to be a valid non-empty string")

	// ErrBadCertMatchByField represents malformed cert_match_by option
	ErrBadCertMatchByField = errors.New("expected 'cert_match_by' to be a valid non-empty string")

	// ErrBadCertMatchField represents malformed cert_match option
	ErrBadCertMatchField = errors.New("expected 'cert_match' to be a valid non-empty string")

	// ErrBadCaCertMatchField represents malformed cert_match option
	ErrBadCaCertMatchField = errors.New("expected 'ca_certs_match' to be a valid non-empty string array")

	// ErrBadCertMatchSkipInvalidField represents malformed cert_match_skip_invalid option
	ErrBadCertMatchSkipInvalidField = errors.New("expected 'cert_match_skip_invalid' to be a boolean")

	// ErrOSNotCompatCertStore represents cert_store passed that exists but is not valid on current OS
	ErrOSNotCompatCertStore = errors.New("cert_store not compatible with current operating system")
)

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Set cert_match_by to a supported non-empty string such as "thumbprint" or "subject".
  2. If using an env variable, confirm it is exported and non-empty for the server process.
  3. Quote the value so YAML/JSON parsers keep it as a string.
  4. Validate the config before deploy to catch the token/line number the configErr reports.

Example fix

// before
cert_match_by: ""
// after
cert_match_by: "thumbprint"
Defensive patterns

Strategy: validation

Validate before calling

if s, ok := cfg.TLS.CertMatchBy.(string); !ok || s == "" {
    return errors.New("cert_match_by must be a non-empty string")
}

Type guard

func isBadCertMatchByField(err error) bool { return errors.Is(err, certstore.ErrBadCertMatchByField) }

Try / catch

if ce, ok := err.(*server.configErr); ok && strings.Contains(ce.Error(), "cert_match_by") {
    // set cert_match_by to a supported value
}

Prevention

When it happens

Trigger: server/opts.go:5284 — TLS config parsing: the cert_match_by value fails the string/non-empty check, producing &configErr{tk, certstore.ErrBadCertMatchByField.Error()} before ParseCertMatchBy runs.

Common situations: Empty cert_match_by left in the config after deleting cert_match, env substitution yielding nothing, or the value written as a YAML key/value mix-up.

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 nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/3f8ab108f6fcd134. Report an issue: GitHub.