fatedier/frp · error
exec configuration is required when type is 'exec'
Error message
exec configuration is required when type is 'exec'
What it means
Thrown by ValueSource.Validate() in frp's config v1 package when a tokenSource (or other ValueSource) declares type: "exec" but the exec sub-object is missing. ValueSource is used to resolve auth tokens dynamically (pkg/config/v1/client.go TokenSource, server.go TokenSource). The switch dispatches validation to the matching sub-config; a nil Exec block cannot be validated.
Source
Thrown at pkg/config/v1/value_source.go:65
Name string `json:"name"`
Value string `json:"value"`
}
// Validate validates the ValueSource configuration.
func (v *ValueSource) Validate() error {
if v == nil {
return errors.New("valueSource cannot be nil")
}
switch v.Type {
case "file":
if v.File == nil {
return errors.New("file configuration is required when type is 'file'")
}
return v.File.Validate()
case "exec":
if v.Exec == nil {
return errors.New("exec configuration is required when type is 'exec'")
}
return v.Exec.Validate()
default:
return fmt.Errorf("unsupported value source type: %s (only 'file' and 'exec' are supported)", v.Type)
}
}
// Resolve resolves the value from the configured source.
func (v *ValueSource) Resolve(ctx context.Context) (string, error) {
if err := v.Validate(); err != nil {
return "", err
}
switch v.Type {
case "file":
return v.File.Resolve(ctx)
case "exec":
return v.Exec.Resolve(ctx)View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Add the exec block under tokenSource: [auth.tokenSource.exec] with command = "..." and optional args/env
- If you meant to read a file, set type = "file" and provide a [auth.tokenSource.file] block with path
- If constructing in Go, populate ValueSource{Type: "exec", Exec: &v1.ExecSource{Command: "..."}}
- Run frpc verify -c ./frpc.toml (or frps verify) to validate before starting
Example fix
# before (frpc.toml) [auth] tokenSource.type = "exec" # after [auth] tokenSource.type = "exec" [auth.tokenSource.exec] command = "/usr/local/bin/get-token" args = ["--audience", "frps"]
Defensive patterns
Strategy: validation
Validate before calling
// Go: validate before use
if vs := cfg.Auth.TokenSource; vs != nil {
if vs.Type == "exec" && vs.Exec == nil {
return fmt.Errorf("tokenSource.type=exec requires an exec block")
}
if err := vs.Validate(); err != nil {
return err
}
} Type guard
func hasExecSource(vs *v1.ValueSource) bool {
return vs != nil && vs.Type == "exec" && vs.Exec != nil
} Prevention
- Always run frpc/frps verify on config changes in CI before deploy
- When templating configs, fail the template when an exec source has no command instead of emitting a half-filled block
When it happens
Trigger: Setting tokenSource.type = "exec" in frpc.toml/frps.toml without a [tokenSource.exec] table; building a v1.ValueSource{Type: "exec"} literal in Go with Exec left nil; marshalling YAML/JSON that omits the exec key.
Common situations: Migrating a static auth.token to an exec-based token source and forgetting the command block; typos like type = "Exec" (case-sensitive, would hit the unsupported-type branch instead) or exEc; configs generated by templates that skip the exec section when a variable is empty.
Related errors
- file path cannot be empty
- cannot specify both auth.token and auth.tokenSource
- invalid auth.tokenSource: %v
- invalid auth method, optional values are %v
- exec command cannot be empty
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/62b9a49a8fc7bcf4.
Report an issue: GitHub.