fatedier/frp · error
failed to decode proxy at index %d: %w
Error message
failed to decode proxy at index %d: %w
What it means
While loading the store, DecodeProxyConfigurerJSON failed for the i-th element of the proxies array. Decoding is two-stage: the entry's "type" discriminator must map to a registered ProxyConfigurer type, then the payload must unmarshal into that type. Because DisallowUnknownFields is false, unknown fields alone do NOT trigger this — a bad/missing "type" string or a structurally incompatible payload does.
Source
Thrown at pkg/config/source/store.go:99
type rawStoreData struct {
Proxies []jsonx.RawMessage `json:"proxies,omitempty"`
Visitors []jsonx.RawMessage `json:"visitors,omitempty"`
}
stored := rawStoreData{}
if err := jsonx.Unmarshal(data, &stored); err != nil {
return fmt.Errorf("failed to parse JSON: %w", err)
}
s.proxies = make(map[string]v1.ProxyConfigurer)
s.visitors = make(map[string]v1.VisitorConfigurer)
for i, proxyData := range stored.Proxies {
proxyCfg, err := v1.DecodeProxyConfigurerJSON(proxyData, v1.DecodeOptions{
DisallowUnknownFields: false,
})
if err != nil {
return fmt.Errorf("failed to decode proxy at index %d: %w", i, err)
}
name := proxyCfg.GetBaseConfig().Name
if name == "" {
return fmt.Errorf("proxy name cannot be empty")
}
s.proxies[name] = proxyCfg
}
for i, visitorData := range stored.Visitors {
visitorCfg, err := v1.DecodeVisitorConfigurerJSON(visitorData, v1.DecodeOptions{
DisallowUnknownFields: false,
})
if err != nil {
return fmt.Errorf("failed to decode visitor at index %d: %w", i, err)
}
name := visitorCfg.GetBaseConfig().Name
if name == "" {
return fmt.Errorf("visitor name cannot be empty")View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Open the store file, navigate to the proxies array element at the index reported in the error message (index is 0-based)
- Verify its "type" value is one of the proxy types supported by the RUNNING frp version (tcp, udp, xtcp, stcp, sudp, http, https, tcpmux, plugin variants)
- If the type is from a newer frp release, upgrade frp to at least the version that wrote the file
- Fix the typo'd/missing "type" field or remove the offending entry, then retry
Example fix
// before (store.json, proxies[2])
{ "type": "htp", "name": "dashboard" }
// after
{ "type": "http", "name": "dashboard" } Defensive patterns
Strategy: validation
Validate before calling
var supportedProxyTypes = map[string]bool{
"tcp": true, "udp": true, "xtcp": true, "stcp": true, "sudp": true,
"http": true, "https": true, "tcpmux": true,
}
func validateStoreTypes(path string) error {
data, _ := os.ReadFile(path)
var raw struct {
Proxies []json.RawMessage `json:"proxies"`
}
if json.Unmarshal(data, &raw) != nil {
return nil // parse errors handled separately
}
for i, p := range raw.Proxies {
var t struct{ Type string `json:"type"` }
if json.Unmarshal(p, &t) != nil || !supportedProxyTypes[t.Type] {
return fmt.Errorf("proxies[%d]: unsupported type %q for this frp build", i, t.Type)
}
}
return nil
} Try / catch
if _, err := source.NewStoreSource(cfg); err != nil {
var idx int
if _, e := fmt.Sscanf(err.Error(), "failed to decode proxy at index %d", &idx); e == nil {
// point operator at the exact array element, suggest version mismatch
}
} Prevention
- Pin the frp version fleet-wide so store files never contain types a binary can't decode
- When downgrading, regenerate the store with the older version before pointing it at the file
- Automate store-file generation through the API rather than writing raw JSON
When it happens
Trigger: A stored proxy entry whose "type" is misspelled ("tcp" vs "tpc") or missing; a store file written by a NEWER frp version containing a proxy type this older build does not know; an entry where the value of "type" is not a string; a payload that cannot unmarshal into the target config struct (e.g. remotePort as a string).
Common situations: Downgrading frp after a newer release wrote modern proxy types into the store; hand-authoring the store file with the wrong discriminator name; a custom/enterprise proxy type that was compiled in before but not in the current binary.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to decode visitor at index %d: %w
- type is required
- failed to parse JSON: %w
- proxy name cannot be empty
- visitor name cannot be empty
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/1524d60c6691a0cc.
Report an issue: GitHub.