grpc/grpc-go · error
xds: failed to JSON unmarshal server configurations during…
Error message
xds: failed to JSON unmarshal server configurations during bootstrap: %v, config: %s
What it means
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.
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.
Example fix
// before (xds_servers not an array)
"xds_servers": {"server_uri":"trafficdirector.googleapis.com:443"}
// after
"xds_servers": [{"server_uri":"trafficdirector.googleapis.com:443","channel_creds":[{"type":"google_default"}]}] Defensive patterns
Strategy: validation
Validate before calling
// Validate that xds_servers is a JSON array of objects before bootstrap.
func validateBootstrapServers(raw json.RawMessage) error {
var arr []json.RawMessage
if err := json.Unmarshal(raw, &arr); err != nil {
return fmt.Errorf("xds_servers must be a JSON array: %w", err)
}
if len(arr) == 0 {
return fmt.Errorf("xds_servers must not be empty")
}
return nil
} Try / catch
// GetConfiguration returns the error; fail fast at startup.
if _, err := bootstrap.GetConfiguration(); err != nil {
log.Fatalf("bootstrap invalid: %v", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- xds: error normalizing JSON bootstrap configuration
- xds: failed to JSON unmarshal server configuration during…
- xds: json.Unmarshal( ) failed during bootstrap
- failed to build credentials bundle from bootstrap for
- failed to unmarshal config
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/05df2203bd9f6fdc.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/bootstrap/bootstrap.go:144
// Equal returns true if scs equals other.
func (scs *ServerConfigs) Equal(other *ServerConfigs) bool {
if len(*scs) != len(*other) {
return false
}
for i := range *scs {
if !(*scs)[i].Equal((*other)[i]) {
return false
}
}
return true
}
// UnmarshalJSON takes the json data (a list of server configurations) and
// unmarshals it to the struct.
func (scs *ServerConfigs) UnmarshalJSON(data []byte) error {
servers := []*ServerConfig{}
if err := json.Unmarshal(data, &servers); err != nil {
return fmt.Errorf("xds: failed to JSON unmarshal server configurations during bootstrap: %v, config:\n%s", err, string(data))
}
*scs = servers
return nil
}
// String returns a string representation of the ServerConfigs, by concatenating
// the string representations of the underlying server configs.
func (scs *ServerConfigs) String() string {
ret := ""
for i, sc := range *scs {
if i > 0 {
ret += ", "
}
ret += sc.String()
}
return ret
}
View on GitHub (pinned to 0c51461d27)