fatedier/frp · error

unsupported value source type: %s (only 'file' and 'exec' ar

Error message

unsupported value source type: %s (only 'file' and 'exec' are supported)

What it means

ValueSource.Validate() rejects a configuration whose `type` field is neither "file" nor "exec". frp's dynamic value resolution (used for auth tokens, etc.) only supports these two source kinds, so any other string fails fast at validation time rather than at resolve time. The error echoes the offending type so the misconfiguration is immediately visible.

Source

Thrown at pkg/config/v1/value_source.go:69

// 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)
	default:
		return "", fmt.Errorf("unsupported value source type: %s", v.Type)
	}
}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Set type to exactly "file" or "exec" (lowercase) in the valueSource block.
  2. If you meant to read a token from disk, use type: file together with a file.path entry.
  3. If you meant to run a helper program (e.g. a cloud IAM token fetcher), use type: exec with exec.command and exec.args.
  4. For environment variables, wrap them: use exec with command: sh, args: [-c, "echo $MY_TOKEN"].

Example fix

// before
ValueSource{Type: "env"}

// after
ValueSource{Type: "file", File: &FileSource{Path: "/etc/frp/token"}}
Defensive patterns

Strategy: validation

Validate before calling

func validateValueSourceType(vs v1.ValueSource) error {
	switch vs.Type {
	case "file":
		if vs.File == nil {
			return fmt.Errorf("type 'file' requires a file block")
		}
	case "exec":
		if vs.Exec == nil {
			return fmt.Errorf("type 'exec' requires an exec block")
		}
	default:
		return fmt.Errorf("unsupported value source type %q (want 'file' or 'exec')", vs.Type)
	}
	return nil
}

Type guard

func isSupportedValueSourceType(t string) bool {
	return t == "file" || t == "exec"
}

Prevention

When it happens

Trigger: Calling ValueSource.Validate() (directly or transitively via ValueSource.Resolve(ctx)) on a ValueSource with Type set to anything other than "file" or "exec" — e.g. Type: "env", Type: "secret", Type: "", or a typo like "File".

Common situations: YAML/JSON frp config uses a valueSource block with an unsupported or misspelled type; a user assumes environment-variable sourcing exists (it does not in this version); an empty type string is left after templating the config.

Related errors


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