coredns/coredns · error

maximum of three arguments allowed for TLS config, found %d

Error message

maximum of three arguments allowed for TLS config, found %d

What it means

NewTLSConfigFromArgs builds a *tls.Config from a variadic argument list that normally comes straight from a Corefile TLS directive. It supports 0-3 arguments (client-cert+key+CA); any call with more than three arguments hits the default branch and returns this error. It is a guard against misconfigured argument arity, thrown before any file I/O happens.

Source

Thrown at plugin/pkg/tls/tls.go:74

	}
	if len(args) > 2 {
		caPath = args[2]
	}
	switch len(args) {
	case 0:
		// No client cert, use system CA
		c, err = NewTLSClientConfig("")
	case 1:
		// No client cert, use specified CA
		c, err = NewTLSClientConfig(certPath)
	case 2:
		// Client cert, use system CA
		c, err = NewTLSConfig(certPath, keyPath, "")
	case 3:
		// Client cert, use specified CA
		c, err = NewTLSConfig(certPath, keyPath, caPath)
	default:
		err = fmt.Errorf("maximum of three arguments allowed for TLS config, found %d", len(args))
	}
	if err != nil {
		return nil, err
	}
	return c, nil
}

// NewTLSConfig returns a TLS config that includes a certificate
// Use for server TLS config or when using a client certificate
// If caPath is empty, system CAs will be used
func NewTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) {
	cert, err := tls.LoadX509KeyPair(certPath, keyPath)
	if err != nil {
		return nil, fmt.Errorf("could not load TLS cert: %s", err)
	}

	roots, err := loadRoots(caPath)
	if err != nil {

View on GitHub (pinned to 558c9757a9)

Solutions

  1. Reduce the arguments to at most three: cert path, key path, CA path (or fewer, per the documented 0/1/2/3-arg forms)
  2. Fix the Corefile TLS directive to match the supported syntax, e.g. 'tls CERT KEY CA' with no extra tokens
  3. If an extra option is genuinely needed, check whether the running CoreDNS version supports it or use a different plugin directive

Example fix

// before
conf := "tls /etc/coredns/cert.pem /etc/coredns/key.pem /etc/coredns/ca.pem extra"
// after
conf := "tls /etc/coredns/cert.pem /etc/coredns/key.pem /etc/coredns/ca.pem"
Defensive patterns

Strategy: validation

Validate before calling

if len(args) > 3 {
    return nil, fmt.Errorf("NewTLSConfigFromArgs: at most 3 args allowed, got %d", len(args))
}
c, err := NewTLSConfigFromArgs(args...)

Prevention

When it happens

Trigger: Calling NewTLSConfigFromArgs with four or more string arguments, e.g. NewTLSConfigFromArgs(cert, key, ca, extra) — typically from parseManualTLS or a plugin constructor (newEtcdPlugin) whose Corefile TLS directive was given too many tokens.

Common situations: A Corefile 'tls' clause that lists cert, key, CA plus a stray trailing token (typo, duplicated path, or extra field not supported by this coredns version); programmatic callers appending an argument beyond the documented 0-3 forms.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


AI-assisted analysis of coredns/coredns@558c9757a9 (2026-09-06). Data as JSON: /api/errors/554590c286975c7a. Report an issue: GitHub.