fatedier/frp · critical

failed to resolve auth.tokenSource: %w

Error message

failed to resolve auth.tokenSource: %w

What it means

BuildClientAuth failed to resolve the dynamic token source: auth.method is 'token' and auth.tokenSource is configured, so the client calls TokenSource.Resolve(context.Background()) at startup to obtain the concrete token, and that external resolution failed. The wrapped error comes from the token source implementation (file read, command exec, or remote fetch).

Source

Thrown at pkg/auth/auth.go:50

	Setter Setter
	key    []byte
}

func (a *ClientAuth) EncryptionKey() []byte {
	return a.key
}

// BuildClientAuth resolves any dynamic auth values and returns a prepared auth runtime.
// Caller must run validation before calling this function.
func BuildClientAuth(cfg *v1.AuthClientConfig) (*ClientAuth, error) {
	if cfg == nil {
		return nil, fmt.Errorf("auth config is nil")
	}
	resolved := *cfg
	if resolved.Method == v1.AuthMethodToken && resolved.TokenSource != nil {
		token, err := resolved.TokenSource.Resolve(context.Background())
		if err != nil {
			return nil, fmt.Errorf("failed to resolve auth.tokenSource: %w", err)
		}
		resolved.Token = token
	}
	setter, err := NewAuthSetter(resolved)
	if err != nil {
		return nil, err
	}
	return &ClientAuth{
		Setter: setter,
		key:    []byte(resolved.Token),
	}, nil
}

func NewAuthSetter(cfg v1.AuthClientConfig) (authProvider Setter, err error) {
	switch cfg.Method {
	case v1.AuthMethodToken:
		authProvider = NewTokenAuth(cfg.AdditionalScopes, cfg.Token)
	case v1.AuthMethodOIDC:

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Run the token source manually as the frpc service user (cat the file or execute the cmd) and fix whatever fails.
  2. If it is a race with secret provisioning, add dependency ordering (e.g., systemd After= on the secret mount) or a wrapper that waits for the token file.
  3. Verify the tokenSource config block matches your frp version's schema.
  4. If dynamic tokens are not required, remove tokenSource and set auth.token directly.

Example fix

# before
[auth]
method = "token"
[auth.tokenSource]
cmd = "/usr/local/bin/get-token"

# after: confirm it runs as the frpc user
sudo -u frpc /usr/local/bin/get-token   # must exit 0 and print the token
Defensive patterns

Strategy: validation

Validate before calling

if cfg.Method == v1.AuthMethodToken && cfg.TokenSource != nil {
    if _, err := cfg.TokenSource.Resolve(context.Background()); err != nil {
        return fmt.Errorf("token source broken before deploy: %w", err)
    }
}

Type guard

func hasResolvableTokenSource(cfg *v1.AuthClientConfig) bool {
    return cfg != nil && cfg.Method == v1.AuthMethodToken && cfg.TokenSource != nil
}

Try / catch

if _, err := auth.BuildClientAuth(cfg); err != nil {
    if strings.Contains(err.Error(), "auth.tokenSource") {
        // provisioning problem: fix the source, don't retry
    }
}

Prevention

When it happens

Trigger: A v1.AuthClientConfig with Method=token and TokenSource set whose Resolve() errors: token file missing or unreadable, exec command returning non-zero, or a token endpoint unreachable.

Common situations: auth.tokenSource file path missing on the frpc host; tokenSource cmd binary not in PATH or failing under the frpc service account; secrets injection (systemd, vault agent) not finished before frpc starts.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/b523bc09f1b035ec. Report an issue: GitHub.