fatedier/frp · error
exec command cannot be empty
Error message
exec command cannot be empty
What it means
Thrown by ExecSource.Validate() when a ValueSource of type "exec" has an empty Command. ExecSource.Resolve launches the command via exec.CommandContext and captures stdout, so a command is mandatory; this check fires before validation of args or env entries.
Source
Thrown at pkg/config/v1/value_source.go:123
}
content, err := os.ReadFile(f.Path)
if err != nil {
return "", fmt.Errorf("failed to read file %s: %v", f.Path, err)
}
// Trim whitespace, which is important for file-based tokens
return strings.TrimSpace(string(content)), nil
}
// Validate validates the ExecSource configuration.
func (e *ExecSource) Validate() error {
if e == nil {
return errors.New("execSource cannot be nil")
}
if e.Command == "" {
return errors.New("exec command cannot be empty")
}
for _, env := range e.Env {
if env.Name == "" {
return errors.New("exec env name cannot be empty")
}
if strings.Contains(env.Name, "=") {
return errors.New("exec env name cannot contain '='")
}
}
return nil
}
// Resolve reads and returns the content captured from stdout of launched subprocess.
func (e *ExecSource) Resolve(ctx context.Context) (string, error) {
if err := e.Validate(); err != nil {
return "", err
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Set tokenSource.exec.command to an executable that prints the token to stdout
- Check TOML/YAML indentation: command must be a key inside [auth.tokenSource.exec]
- Confirm the command is on PATH or use an absolute path
- Validate with frpc verify -c ./frpc.toml before restart
Example fix
# before [auth.tokenSource.exec] args = ["--json"] # after [auth.tokenSource.exec] command = "cloudctl" args = ["--json", "token", "print"]
Defensive patterns
Strategy: validation
Validate before calling
if vs := cfg.Auth.TokenSource; vs != nil && vs.Type == "exec" && vs.Exec != nil {
if vs.Exec.Command == "" {
return fmt.Errorf("tokenSource.exec.command is empty")
}
} Type guard
func hasCommand(e *v1.ExecSource) bool {
return e != nil && strings.TrimSpace(e.Command) != ""
} Prevention
- Smoke-test the token command manually (it must print the token to stdout) before configuring it
- Use absolute paths for the command to avoid PATH differences under systemd/containers
When it happens
Trigger: tokenSource.exec table present but command key missing or empty; Go literal v1.ExecSource{Args: []string{"--flag"}} with Command unset; YAML indentation mistake putting command under the wrong table so it is not decoded.
Common situations: Commenting out the command while testing; config templates that inject the command from an environment variable that is unset; switching from file to exec token source and only copying args/env.
Related errors
- exec env name cannot be empty
- exec env name cannot contain '='
- exec configuration is required when type is 'exec'
- file path cannot be empty
- first and second range numbers are not in pairs
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/f817eb2a63c08734.
Report an issue: GitHub.