nsqio/nsq · error

unknown tlsVersionOption %q

Error message

unknown tlsVersionOption %q

What it means

tlsMinVersionOption.Set (apps/nsqd/options.go) parses the --tls-min-version flag by lowercasing the value and matching it against tlsVersionTable, whose only accepted strings are 'tls1.0', 'tls1.1', 'tls1.2' and 'tls1.3' (mapping to the crypto/tls version constants; an empty string is allowed and means default). Anything else returns 'unknown tlsVersionOption %q', and because flag parsing fails, nsqd exits before serving.

Source

Thrown at apps/nsqd/options.go:63

}{
	{tls.VersionTLS10, "tls1.0"},
	{tls.VersionTLS11, "tls1.1"},
	{tls.VersionTLS12, "tls1.2"},
	{tls.VersionTLS13, "tls1.3"},
}

func (t *tlsMinVersionOption) Set(s string) error {
	s = strings.ToLower(s)
	if s == "" {
		return nil
	}
	for _, v := range tlsVersionTable {
		if s == v.str {
			*t = tlsMinVersionOption(v.val)
			return nil
		}
	}
	return fmt.Errorf("unknown tlsVersionOption %q", s)
}

func (t *tlsMinVersionOption) Get() interface{} { return uint16(*t) }

func (t *tlsMinVersionOption) String() string {
	for _, v := range tlsVersionTable {
		if uint16(*t) == v.val {
			return v.str
		}
	}
	return strconv.FormatInt(int64(*t), 10)
}

type config map[string]interface{}

// Validate settings in the config file, and fatal on errors
func (cfg config) Validate() {
	// special validation/translation

View on GitHub (pinned to 85cf10c09c)

Solutions

  1. Use one of the exact tokens: --tls-min-version=tls1.2 (or tls1.0, tls1.1, tls1.3; any case is accepted).
  2. Remove the flag entirely to accept nsqd's compiled default minimum version.
  3. Check for stray quotes/whitespace in systemd/compose files that make the value 'tls1.2\n' or '\'tls1.2\''.
  4. If you were trying ssl3.0/tls1.0 for legacy clients, know that ssl3.0 is not in the table and modern Go builds cannot offer it.

Example fix

# before
nsqd --tls-min-version=1.2
# unknown tlsVersionOption "1.2"

# after
nsqd --tls-min-version=tls1.2
Defensive patterns

Strategy: validation

Validate before calling

var tlsVersions = map[string]bool{"tls1.0": true, "tls1.1": true, "tls1.2": true, "tls1.3": true}

if v := os.Getenv("NSQD_TLS_MIN_VERSION"); v != "" && !tlsVersions[strings.ToLower(v)] {
    log.Fatalf("--tls-min-version must be one of tls1.0..tls1.3, got %q", v)
}

Type guard

func isValidTLSVersion(s string) bool {
    switch strings.ToLower(s) {
    case "tls1.0", "tls1.1", "tls1.2", "tls1.3":
        return true
    }
    return false
}

Try / catch

// config loaders: parse flags into an error, then report valid tokens together
if err := flags.Parse(os.Args[1:]); err != nil {
    if strings.Contains(err.Error(), "unknown tlsVersionOption") {
        return fmt.Errorf("bad --tls-min-version; allowed: tls1.0, tls1.1, tls1.2, tls1.3")
    }
}

Prevention

When it happens

Trigger: Passing --tls-min-version=1.2, --tls-min-version=TLSv1.2, --tls-min-version=ssl3.0, or any string other than tls1.0-tls1.3 (case-insensitive). The value is lowercased first, so 'TLS1.2' is fine but version numbers without the 'tls' prefix are not; SSLv3 has no entry and cannot be selected at all.

Common situations: Translating config from other software (nginx ssl_protocols TLSv1.2, grpc '1.2' style) into nsqd flags; hardening scripts that set --tls-min-version=1.3 expecting numeric syntax; someone trying to re-enable SSLv3 for a legacy consumer (not supported).

Related errors


AI-assisted analysis of nsqio/nsq@85cf10c09c (2026-08-16). Data as JSON: /api/errors/fe32104d69d6fb61. Report an issue: GitHub.