temporalio/temporal · error

global.authorization.remoteClusterAuth.require is true but n

Error message

global.authorization.remoteClusterAuth.require is true but no TokenProvider is configured: use WithTokenProvider

What it means

ServerOptionsProvider validates remote-cluster authorization settings at server construction. If global.authorization.remoteClusterAuth.require is enabled, a TokenProvider must be registered via WithTokenProvider; otherwise cross-cluster requests cannot be authenticated, so the provider fails fast with this error.

Source

Thrown at temporal/fx.go:298

		esClient, err = esclient.NewClient(esConfig, esHttpClient, logger)
		if err != nil {
			return serverOptionsProvider{}, fmt.Errorf("unable to create Elasticsearch client (URL = %v, username = %q): %w",
				esConfig.URL.Redacted(), esConfig.Username, err)
		}
	}

	// check that when static hosts are defined, they are defined for all required hosts
	if len(so.hostsByService) > 0 {
		for _, service := range DefaultServices {
			hosts := so.hostsByService[primitives.ServiceName(service)]
			if len(hosts.All) == 0 {
				return serverOptionsProvider{}, fmt.Errorf("%w: %v", missingServiceInStaticHosts, service)
			}
		}
	}

	if so.config.Global.Authorization.RemoteClusterAuth.Require && so.tokenProvider == nil {
		return serverOptionsProvider{}, errors.New("global.authorization.remoteClusterAuth.require is true but no TokenProvider is configured: use WithTokenProvider")
	}
	// TokenCredentials require TLS (RFC 9700); without a remote-cluster TLS source the first
	// cross-cluster dial would fatal-log, with no clear "you forgot TLS" diagnostic.
	// Coarse check: any remote-cluster TLS entry passes; per-hostname config is still validated
	// lazily on first dial.
	if so.tokenProvider != nil && so.tlsConfigProvider == nil && len(so.config.Global.TLS.RemoteClusters) == 0 {
		return serverOptionsProvider{}, errors.New("WithTokenProvider is set but no remote-cluster TLS is configured: supply global.tls.remoteClusters in config, or pass a provider via WithTLSConfigProvider")
	}

	return serverOptionsProvider{
		ServerOptions:              so,
		StopChan:                   stopChan,
		StartupSynchronizationMode: so.startupSynchronizationMode,

		Config:      so.config,
		PProfConfig: &so.config.Global.PProf,
		LogConfig:   so.config.Log,

View on GitHub (pinned to bde624efd1)

Solutions

  1. Call WithTokenProvider(...) with an implementation that returns valid tokens when building server options
  2. If remote cluster auth is not needed, set global.authorization.remoteClusterAuth.require to false in config
  3. Review the fx boot logs for the wrapped error to confirm which service bootstrap failed
  4. Add a startup test asserting the options provider builds successfully with your production config

Example fix

// before
server := temporal.NewServerFxdist(..., temporal.WithConfig(cfg)) // no token provider
// after
server := temporal.NewServerFxdist(...,
    temporal.WithConfig(cfg),
    temporal.WithTokenProvider(myTokenProvider),
)
Defensive patterns

Strategy: validation

Validate before calling

func validateRemoteAuth(cfg *config.Config, opts []temporal.ServerOption) error {
    if cfg.Global.Authorization.RemoteClusterAuth.Require {
        for _, o := range opts {
            if _, ok := o.(temporal.TokenProviderOption); ok { return nil }
        }
        return errors.New("remoteClusterAuth.require is on: pass WithTokenProvider")
    }
    return nil
}

Try / catch

provider, err := temporal.ServerOptionsProvider(...)
if err != nil {
    if strings.Contains(err.Error(), "no TokenProvider is configured") {
        return fmt.Errorf("bootstrap: attach a token provider for remote cluster auth: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Programmatically building server options with config requiring remote cluster auth (Global.Authorization.RemoteClusterAuth.Require == true) while never calling WithTokenProvider on the options builder.

Common situations: Enabling remoteClusterAuth.require in temporal.yaml for cross-cluster (multi-region/replication) setups but forgetting the token provider in embedded-server code; copying server bootstrap code from a single-cluster example into an authorized multi-cluster deployment.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/2bea61e7d3ec0ede. Report an issue: GitHub.