fatedier/frp · error

exec env name cannot contain '='

Error message

exec env name cannot contain '='

What it means

Thrown by ExecSource.Validate() when an env entry's Name contains '='. exec.Cmd.Env expects KEY=VALUE strings; an '=' inside the key would corrupt that format, so frp rejects it up front. Values may still contain '='; only the name is checked.

Source

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

	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
	}

	cmd := exec.CommandContext(ctx, e.Command, e.Args...)
	if len(e.Env) != 0 {
		cmd.Env = os.Environ()
		for _, env := range e.Env {
			cmd.Env = append(cmd.Env, env.Name+"="+env.Value)
		}
	}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Put only the variable name in name and the remainder in value: { name = "FOO", value = "bar" }
  2. If generating config programmatically, split each KEY=VALUE on the first '=' only (strings.SplitN(s, "=", 2))
  3. Re-run frpc verify to confirm

Example fix

# before
[[auth.tokenSource.exec.env]]
name = "FOO=bar"
value = ""

# after
[[auth.tokenSource.exec.env]]
name = "FOO"
value = "bar"
Defensive patterns

Strategy: validation

Validate before calling

for _, kv := range vs.Exec.Env {
    if strings.Contains(kv.Name, "=") {
        return fmt.Errorf("env name %q must not contain '='", kv.Name)
    }
}

Type guard

func isPlainEnvName(name string) bool {
    return name != "" && !strings.ContainsAny(name, "=")
}

Prevention

When it happens

Trigger: tokenSource.exec.env entry like { name = "A=B", value = "1" }; building env from a raw string split on the first '=' incorrectly in code that generates frp config; copy-pasting a full KEY=VALUE pair into the name field.

Common situations: Users pasting "FOO=bar" into the name slot; config generators that split environment lines on the wrong delimiter; secrets wrappers that embed '=' in variable names.

Related errors


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