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
- Reduce the arguments to at most three: cert path, key path, CA path (or fewer, per the documented 0/1/2/3-arg forms)
- Fix the Corefile TLS directive to match the supported syntax, e.g. 'tls CERT KEY CA' with no extra tokens
- 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
- Validate Corefile TLS directive token count before constructing args
- Keep the directive to the documented forms: tls, tls CA, tls CERT KEY, tls CERT KEY CA
- Add a config-lint test that calls NewTLSConfigFromArgs with each deployed TLS directive
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.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- resolving ACME storage directory: %w
- invalid ACME CA URL %q
- invalid ACME resolver %q: %w
- reload duration value is expected
- invalid duration
AI-assisted analysis of coredns/coredns@558c9757a9 (2026-09-06).
Data as JSON: /api/errors/554590c286975c7a.
Report an issue: GitHub.