{"record":{"id":"05df2203bd9f6fdc","repo":"grpc/grpc-go","slug":"xds-failed-to-json-unmarshal-server-configuration","errorCode":null,"errorMessage":"xds: failed to JSON unmarshal server configurations during bootstrap: %v, config:\n%s","messagePattern":"xds: failed to JSON unmarshal server configurations during bootstrap: (.+?), config:\n(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/xds/bootstrap/bootstrap.go","lineNumber":144,"sourceCode":"// Equal returns true if scs equals other.\nfunc (scs *ServerConfigs) Equal(other *ServerConfigs) bool {\n\tif len(*scs) != len(*other) {\n\t\treturn false\n\t}\n\tfor i := range *scs {\n\t\tif !(*scs)[i].Equal((*other)[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// UnmarshalJSON takes the json data (a list of server configurations) and\n// unmarshals it to the struct.\nfunc (scs *ServerConfigs) UnmarshalJSON(data []byte) error {\n\tservers := []*ServerConfig{}\n\tif err := json.Unmarshal(data, &servers); err != nil {\n\t\treturn fmt.Errorf(\"xds: failed to JSON unmarshal server configurations during bootstrap: %v, config:\\n%s\", err, string(data))\n\t}\n\t*scs = servers\n\treturn nil\n}\n\n// String returns a string representation of the ServerConfigs, by concatenating\n// the string representations of the underlying server configs.\nfunc (scs *ServerConfigs) String() string {\n\tret := \"\"\n\tfor i, sc := range *scs {\n\t\tif i > 0 {\n\t\t\tret += \", \"\n\t\t}\n\t\tret += sc.String()\n\t}\n\treturn ret\n}\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/bootstrap/bootstrap.go#L126-L162","documentation":"Returned by ServerConfigs.UnmarshalJSON (internal/xds/bootstrap/bootstrap.go:143) when the top-level `xds_servers` array fails to unmarshal into []*ServerConfig. This happens during bootstrap parsing (GetConfiguration/NewConfigFromContents) and is fatal: the xDS client cannot start without valid server configs.","triggerScenarios":"Bootstrap JSON's `xds_servers` field is not a valid JSON array of server objects — e.g. it is a string, an object instead of an array, or contains malformed entries that fail ServerConfig unmarshalling.","commonSituations":"Hand-edited bootstrap file with a structural mistake; GRPC_XDS_BOOTSTRAP points at a truncated/corrupt file; GRPC_XDS_BOOTSTRAP_CONFIG env var holds invalid JSON; a server entry missing required fields.","solutions":["Validate the bootstrap file with a JSON linter and against the xDS bootstrap schema","Ensure `xds_servers` is an array of objects each with `server_uri` and `channel_creds`","Point GRPC_XDS_BOOTSTRAP at a known-good file (re-check the path)"],"exampleFix":"// before\n{\"xds_servers\":{\"server_uri\":\"trafficdirector.googleapis.com\"}}\n// after\n{\"xds_servers\":[{\"server_uri\":\"trafficdirector.googleapis.com\",\"channel_creds\":[{\"type\":\"google_default\"}]}]}","handlingStrategy":"validation","validationCode":"// Validate the bootstrap file before feeding it to the xDS client.\ndata, err := os.ReadFile(bootstrapPath)\nif err != nil { return err }\nif !json.Valid(data) {\n    return fmt.Errorf(\"bootstrap file %q is not valid JSON\", bootstrapPath)\n}\nvar probe struct{ XDSServers []json.RawMessage `json:\"xds_servers\"` }\nif err := json.Unmarshal(data, &probe); err != nil || len(probe.XDSServers) == 0 {\n    return fmt.Errorf(\"bootstrap `xds_servers` missing or invalid: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"cfg, err := bootstrap.GetConfiguration()\nif err != nil {\n    log.Fatalf(\"xDS bootstrap failed; check GRPC_XDS_BOOTSTRAP: %v\", err)\n}","preventionTips":["Lint the bootstrap JSON in CI","Keep a known-good bootstrap file as a golden test fixture","Confirm GRPC_XDS_BOOTSTRAP points to the right path per environment"],"tags":["grpc","xds","bootstrap","config","go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}