fatedier/frp · error

failed to set config source: %w

Error message

failed to set config source: %w

What it means

While starting an inline frpc service with explicitly provided proxy/visitor configurers, source.NewConfigSource().ReplaceAll(proxyCfgs, visitorCfgs) failed. ReplaceAll validates and normalizes every configurer before storing it, so one of the supplied proxy or visitor configs is invalid at the source layer.

Source

Thrown at cmd/frpc/sub/proxy.go:147

			err := startService(clientCfg, nil, []v1.VisitorConfigurer{visitorCfg}, unsafeFeatures, "")
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		},
	}
}

func startService(
	cfg *v1.ClientCommonConfig,
	proxyCfgs []v1.ProxyConfigurer,
	visitorCfgs []v1.VisitorConfigurer,
	unsafeFeatures *security.UnsafeFeatures,
	cfgFile string,
) error {
	configSource := source.NewConfigSource()
	if err := configSource.ReplaceAll(proxyCfgs, visitorCfgs); err != nil {
		return fmt.Errorf("failed to set config source: %w", err)
	}
	aggregator := source.NewAggregator(configSource)
	return startServiceWithAggregator(cfg, aggregator, unsafeFeatures, cfgFile)
}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Log the wrapped inner error; it names the exact offending configurer, so fix that entry's name/type fields.
  2. Validate each configurer before calling startService (see defense snippet) so bad entries fail with better context.
  3. Deduplicate proxy/visitor names before assembly.

Example fix

// before
err := svc.Start()

// after: pre-validate to surface the bad configurer with its name
for _, p := range proxyCfgs {
    base := p.GetBaseConfig()
    if base == nil || base.Name == "" {
        return fmt.Errorf("proxy configurer with empty name")
    }
}
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
for _, p := range proxyCfgs {
    b := p.GetBaseConfig()
    if b == nil || b.Name == "" || seen[b.Name] {
        return fmt.Errorf("invalid or duplicate proxy configurer")
    }
    seen[b.Name] = true
}

Try / catch

if err := configSource.ReplaceAll(proxyCfgs, visitorCfgs); err != nil {
    return fmt.Errorf("config rejected: %w", err) // inner error names the entry
}

Prevention

When it happens

Trigger: Calling startService with a slice containing a configurer whose type or name is unsupported, empty, duplicated, or whose concrete type the source layer cannot handle.

Common situations: Embedding frpc and passing programmatically built v1.ProxyConfigurer objects with missing required fields; duplicate proxy names across the supplied slices; a nil or wrong-typed configurer slipping into the slice during refactoring.

Related errors


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