fatedier/frp · error
file configuration is required when type is 'file'
Error message
file configuration is required when type is 'file'
What it means
Validation error from ValueSource.Validate: the value source is declared with type "file" but its File sub-configuration is nil. ValueSource lets config fields (e.g. auth.token, oidc clientSecret) be read from a file or a command instead of a literal value; type "file" requires a matching {path: ...} object describing which file to read. The check runs whenever the config loader validates a ValueSource-typed field.
Source
Thrown at pkg/config/v1/value_source.go:60
Args []string `json:"args,omitempty"`
Env []ExecEnvVar `json:"env,omitempty"`
}
type ExecEnvVar struct {
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
}
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Supply the file block: {type = "file", file = {path = "/run/secrets/token"}} so File is non-nil.
- Check indentation/nesting: the path key must live inside the file table, not beside type.
- If the value should come from a command, use type = "exec" with exec = {command = [...]} instead.
- Verify the referenced path exists and is readable by the frp process to avoid the later file-open failure.
Example fix
# before
[auth]
token = {type = "file"}
# after
[auth]
token = {type = "file", file = {path = "/run/secrets/frp-token"}} Defensive patterns
Strategy: validation
Validate before calling
func valueSourceWellFormed(vs *v1.ValueSource) error {
if vs == nil {
return nil // field not using a value source
}
switch vs.Type {
case "file":
if vs.File == nil {
return errors.New("type=file requires a file block with path")
}
case "exec":
if vs.Exec == nil {
return errors.New("type=exec requires an exec block")
}
}
return nil
} Type guard
func valueSourceComplete(vs v1.ValueSource) bool {
switch vs.Type {
case "file":
return vs.File != nil
case "exec":
return vs.Exec != nil
default:
return false
}
} Try / catch
if err := vs.Validate(); err != nil {
if strings.Contains(err.Error(), "file configuration is required") {
// add file = {path = ...} beside type = "file"
}
return err
} Prevention
- Pair every type = "file" with file = {path = ...} in the same block.
- Prefer TOML inline tables for value sources to keep them on one line.
- Secret-sourcing changes should always be followed by frpc verify / frps verify.
When it happens
Trigger: A config field using value source syntax with type = "file" but no accompanying file block — e.g. {type = "file"} alone, or the file table nested under the wrong key so File decodes to nil. Also triggered in Go by constructing v1.ValueSource{Type: "file"} without setting File.
Common situations: Migrating secrets from literal strings to file-based sourcing and stopping halfway; YAML/TOML indentation errors putting the path key outside the file table; typo 'path' vs the expected key; JSON configs where "file": null.
Related errors
- unsupported value source type: %s (only 'file' and 'exec' ar
- unsupported value source type: %s
- auth.oidc.clientID is required; auth.oidc.tokenEndpointURL i
- localAddr is required
- localPath is required
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/fef4979b317f4513.
Report an issue: GitHub.