grpc/grpc-go · error
xds: json.Unmarshal(%s) failed during bootstrap: %v
Error message
xds: json.Unmarshal(%s) failed during bootstrap: %v
What it means
This error fires inside Config.UnmarshalJSON (bootstrap.go:598) when Go's encoding/json cannot parse the raw bootstrap bytes into the configJSON struct. It means the bootstrap content is not valid JSON or contains a field whose value type does not match the expected struct tag. The original data is echoed in the message so you can see exactly what bytes failed.
Source
Thrown at internal/xds/bootstrap/bootstrap.go:598
XDSServers: c.xDSServers,
CertificateProviders: c.cpcs,
ServerListenerResourceNameTemplate: c.serverListenerResourceNameTemplate,
ClientDefaultListenerResourceNameTemplate: c.clientDefaultListenerResourceNameTemplate,
Authorities: c.authorities,
Node: c.node,
}
return json.MarshalIndent(config, " ", " ")
}
// UnmarshalJSON takes the json data (the complete bootstrap configuration) and
// unmarshals it to the struct.
func (c *Config) UnmarshalJSON(data []byte) error {
// Initialize the node field with client controlled values. This ensures
// even if the bootstrap configuration did not contain the node field, we
// will have a node field with client controlled fields alone.
config := configJSON{Node: newNode()}
if err := json.Unmarshal(data, &config); err != nil {
return fmt.Errorf("xds: json.Unmarshal(%s) failed during bootstrap: %v", string(data), err)
}
c.xDSServers = config.XDSServers
c.cpcs = config.CertificateProviders
c.serverListenerResourceNameTemplate = config.ServerListenerResourceNameTemplate
c.clientDefaultListenerResourceNameTemplate = config.ClientDefaultListenerResourceNameTemplate
c.authorities = config.Authorities
c.node = config.Node
// Build the certificate providers configuration to ensure that it is valid.
cpcCfgs := make(map[string]*certprovider.BuildableConfig)
getBuilder := internal.GetCertificateProviderBuilder.(func(string) certprovider.Builder)
for instance, nameAndConfig := range c.cpcs {
name := nameAndConfig.PluginName
parser := getBuilder(nameAndConfig.PluginName)
if parser == nil {
// We ignore plugins that we do not know about.
continueView on GitHub (pinned to 03255a9237)
Solutions
- Run the bootstrap content through a JSON linter (e.g. jq . < bootstrap.json) to find the syntax error and fix it.
- Compare the structure field-by-field against the configJSON struct tags in bootstrap.go (xds_servers, certificate_providers, node, authorities, etc.) and correct any type mismatches.
- If the file is injected by a sidecar or controller, verify the injector template and the mounted file contents rather than editing in-pod.
- Add a startup self-check that calls NewConfigFromContents on the file before the gRPC channel is created so the failure surfaces early with a clear log line.
Example fix
// before — file contains a trailing comma:
// "xds_servers": [ {...}, ],
// "node": { "id": "x" }
//
// after — remove trailing comma:
// "xds_servers": [ {...} ],
// "node": { "id": "x" } Defensive patterns
Strategy: validation
Validate before calling
// Validate bootstrap JSON before passing to NewConfigFromContents.
func validateBootstrapJSON(data []byte) error {
var probe map[string]json.RawMessage
if err := json.Unmarshal(data, &probe); err != nil {
return fmt.Errorf("bootstrap is not valid JSON: %w", err)
}
return nil
}
// usage:
// if err := validateBootstrapJSON(data); err != nil { return err }
// cfg, err := bootstrap.NewConfigFromContents(data) Try / catch
// When reading the bootstrap at startup, wrap NewConfigFromContents:
cfg, err := bootstrap.NewConfigFromContents(data)
if err != nil {
return fmt.Errorf("fatal: bootstrap config invalid, application cannot start: %w", err)
}
// Do not fall back to defaults silently — fail fast. Prevention
- Lint the bootstrap JSON in CI with jq or a JSON schema before deploying.
- Generate bootstrap files with a templating system that produces valid JSON, not hand-editing.
- Add a startup readiness probe that calls NewConfigFromContents so misconfiguration blocks startup visibly.
When it happens
Trigger: Calling NewConfigFromContents or GetConfiguration with a bootstrap whose JSON is syntactically broken (trailing comma, unquoted key, stray characters) or whose field values have the wrong type (e.g. xds_servers as a string instead of an array). Any path through UnmarshalJSON where json.Unmarshal(data, &config) returns non-nil hits this.
Common situations: The GRPC_XDS_BOOTSTRAP file was hand-edited and a typo was introduced; a templating/sidecar injector produced truncated JSON; a copy-paste left a YAML fragment in a JSON file; the node field was set to a string instead of an object.
Related errors
- xds: error normalizing JSON bootstrap configuration: %v
- missing server_listener_resource_name_template in the bootst
- xds: failed to JSON unmarshal server configurations during b
- xds: failed to JSON unmarshal server configuration during bo
- failed to build credentials bundle from bootstrap for %q: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/cbfbf1d0667fc52e.
Report an issue: GitHub.