netbirdio/netbird · error

auth is not supported for TLS services

Error message

auth is not supported for TLS services

What it means

Returned by validateTLSMode when isAuthEnabled() is true on a tls service. TLS mode is an encrypted byte passthrough keyed by SNI: the proxy never decrypts the stream (no termination on an HTTP layer it controls), so it cannot run password/pin/bearer/header challenges. All four auth types are checked, same as for tcp/udp.

Source

Thrown at management/internals/modules/reverseproxy/service/service.go:941

	}
	if s.isAuthEnabled() {
		return errors.New("auth is not supported for TCP/UDP services")
	}
	if len(s.Targets) != 1 {
		return errors.New("TCP/UDP services must have exactly one target")
	}
	if s.Mode == ModeUDP && s.Targets[0].ProxyProtocol {
		return errors.New("proxy_protocol is not supported for UDP services")
	}
	return s.validateL4Target(s.Targets[0])
}

func (s *Service) validateTLSMode() error {
	if s.Domain == "" {
		return errors.New("domain is required for TLS services (used for SNI matching)")
	}
	if s.isAuthEnabled() {
		return errors.New("auth is not supported for TLS services")
	}
	if s.ListenPort == 0 {
		return errors.New("listen_port is required for TLS services")
	}
	if len(s.Targets) != 1 {
		return errors.New("TLS services must have exactly one target")
	}
	return s.validateL4Target(s.Targets[0])
}

func (s *Service) validateHTTPTargets() error {
	for i, target := range s.Targets {
		switch target.TargetType {
		case TargetTypePeer, TargetTypeHost, TargetTypeDomain:
			// Host is normally overwritten by replaceHostByLookup with the
			// resolved peer IP / resource address; operator-supplied values
			// are honored only when DirectUpstream is set. Validate the
			// override here so misconfigured hosts fail fast at API time.

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Remove or disable every auth block on the tls service.
  2. Use mode http with an https target_protocol if you want the proxy to terminate TLS and authenticate users.
  3. Control reachability with NetBird access groups, ACLs, or access_restrictions instead.

Example fix

// before
{ "mode": "tls", "listen_port": 636,
  "auth": { "bearer_auth": { "enabled": true, "distribution_groups": ["admins"] } },
  "targets": [...] }

// after
{ "mode": "tls", "listen_port": 636, "targets": [...] }
Defensive patterns

Strategy: validation

Validate before calling

func checkTLSNoAuth(mode string, auth AuthConfig) error {
	if mode == "tls" && anyAuthEnabled(auth) {
		return errors.New("strip all auth blocks for tls services")
	}
	return nil
}

Type guard

func isTLSAuthClean(mode string, auth AuthConfig) bool {
	return mode != "tls" || !anyAuthEnabled(auth)
}

Try / catch

if err := svc.Validate(); err != nil {
	if strings.Contains(err.Error(), "auth is not supported for TLS") {
		return respondBadRequest(errors.New("use http mode for authenticated access"))
	}
	return respondBadRequest(err)
}

Prevention

When it happens

Trigger: Submitting a tls service with auth.password_auth / pin_auth / bearer_auth enabled or any enabled header_auths entry; converting an HTTPS service that had SSO (bearer auth) into tls passthrough without removing the auth block.

Common situations: Wanting 'secure' database TLS forwarding with a login prompt and not realizing auth is an HTTP-mode feature. Template reuse from an authenticated HTTP service. Upgrades where previously ignored auth fields on tls services now fail validation.

Understand the failure class

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/8545261c247160c6. Report an issue: GitHub.