grpc/grpc-go · error
xds: error normalizing JSON bootstrap configuration: %v
Error message
xds: error normalizing JSON bootstrap configuration: %v
What it means
NewConfigFromContents first runs json.Indent on the raw bytes to normalize whitespace (bootstrap.go:692-694). json.Indent requires well-formed JSON input; if the bytes are not valid JSON it returns an error that is wrapped here. This is an earlier, stricter check than UnmarshalJSON and catches malformed input before the structured parse even begins.
Source
Thrown at internal/xds/bootstrap/bootstrap.go:694
if fContent != "" {
if logger.V(2) {
logger.Infof("Using bootstrap contents from GRPC_XDS_BOOTSTRAP_CONFIG environment variable")
}
return NewConfigFromContents([]byte(fContent))
}
return nil, nil
}
// NewConfigFromContents creates a new bootstrap configuration from the provided
// contents.
func NewConfigFromContents(data []byte) (*Config, error) {
// Normalize the input configuration.
buf := bytes.Buffer{}
err := json.Indent(&buf, data, "", "")
if err != nil {
return nil, fmt.Errorf("xds: error normalizing JSON bootstrap configuration: %v", err)
}
data = bytes.TrimSpace(buf.Bytes())
config := &Config{}
if err := config.UnmarshalJSON(data); err != nil {
return nil, err
}
return config, nil
}
// ConfigOptionsForTesting specifies options for creating a new bootstrap
// configuration for testing purposes.
//
// # Testing-Only
type ConfigOptionsForTesting struct {
// Servers is the top-level xDS server configuration. It contains a list of
// server configurations.
Servers json.RawMessageView on GitHub (pinned to 03255a9237)
Solutions
- Confirm the input is JSON by piping it through jq or a JSON parser.
- If you have YAML, convert it to JSON before setting GRPC_XDS_BOOTSTRAP_CONFIG or writing the file.
- Ensure the full content is present — check for truncation in env var injection or ConfigMap size limits.
- For empty input, note that GetConfiguration returns (nil, nil) when neither env var is set, so this error specifically means a non-empty but invalid value.
Example fix
// before: GRPC_XDS_BOOTSTRAP_CONFIG contains YAML
// xds_servers:
// - server_uri: dns:///xds:443
// after: provide valid JSON
// {"xds_servers":[{"server_uri":"dns:///xds:443"}]} Defensive patterns
Strategy: validation
Validate before calling
// Confirm the contents are JSON before NewConfigFromContents.
func isValidJSON(data []byte) error {
var buf bytes.Buffer
if err := json.Indent(&buf, data, "", ""); err != nil {
return fmt.Errorf("not valid JSON: %w", err)
}
return nil
} Prevention
- Never pass YAML into GRPC_XDS_BOOTSTRAP_CONFIG; convert to JSON first.
- Check ConfigMap/secret size limits that could truncate inline content.
- Validate inline bootstrap content in CI before injecting it as an env var.
When it happens
Trigger: Calling NewConfigFromContents (or GetConfiguration via GRPC_XDS_BOOTSTRAP_CONFIG) with bytes that are not valid JSON — empty bytes, a YAML/markup document, a protobuf binary, or truncated JSON. json.Indent fails before any field-level parsing.
Common situations: Passing a YAML bootstrap where JSON was expected; an env var contains a base64 or otherwise encoded blob that was not decoded first; the content was truncated by a shell or config-map size limit.
Related errors
- xds: json.Unmarshal(%s) failed during bootstrap: %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/e64f6cff1245ffb2.
Report an issue: GitHub.