{"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":"error","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/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/bootstrap/bootstrap.go#L126-L162","documentation":"Returned by ServerConfigs.UnmarshalJSON when the 'xds_servers' array of the bootstrap file cannot be unmarshalled into []*ServerConfig. The offending JSON payload is included so you can see the exact malformed input.","triggerScenarios":"Triggered at bootstrap.go:144 when json.Unmarshal(data, &servers) fails for the xds_servers field. Typically the value is not a JSON array, or contains elements that are not objects convertible to ServerConfig.","commonSituations":"xds_servers set to a single object instead of an array; array elements are strings or numbers instead of objects; stray trailing comma producing invalid JSON; copy-paste error merging two bootstrap files.","solutions":["Open the bootstrap file and confirm xds_servers is a JSON array of server objects.","Run the file through a JSON validator (e.g. jq . bootstrap.json) to surface syntax errors.","Ensure each element has the expected fields (server_uri, channel_creds).","Regenerate the bootstrap from your control-plane tooling (e.g. gke xds bootstrap generator) if hand-editing introduced errors."],"exampleFix":"// before (xds_servers not an array)\n\"xds_servers\": {\"server_uri\":\"trafficdirector.googleapis.com:443\"}\n\n// after\n\"xds_servers\": [{\"server_uri\":\"trafficdirector.googleapis.com:443\",\"channel_creds\":[{\"type\":\"google_default\"}]}]","handlingStrategy":"validation","validationCode":"// Validate that xds_servers is a JSON array of objects before bootstrap.\nfunc validateBootstrapServers(raw json.RawMessage) error {\n    var arr []json.RawMessage\n    if err := json.Unmarshal(raw, &arr); err != nil {\n        return fmt.Errorf(\"xds_servers must be a JSON array: %w\", err)\n    }\n    if len(arr) == 0 {\n        return fmt.Errorf(\"xds_servers must not be empty\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// GetConfiguration returns the error; fail fast at startup.\nif _, err := bootstrap.GetConfiguration(); err != nil {\n    log.Fatalf(\"bootstrap invalid: %v\", err)\n}","preventionTips":["Lint the bootstrap file with jq before deploying.","Generate bootstrap files from templates rather than hand-editing.","Store a known-good bootstrap in version control for comparison."],"tags":["grpc","xds","bootstrap","config","json","go"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}