grpc/grpc-go · error
xds: failed to read bootstrap config from file %q: %v
Error message
xds: failed to read bootstrap config from file %q: %v
What it means
GetConfiguration reads the bootstrap file path from GRPC_XDS_BOOTSTRAP and attempts to os.ReadFile it (bootstrap.go:670-672). If the read itself fails (file does not exist, permission denied, I/O error), this error wraps the OS-level error with the filename so you know which path failed.
Source
Thrown at internal/xds/bootstrap/bootstrap.go:672
//
// This function tries to process as much of the bootstrap file as possible (in
// the presence of the errors) and may return a Config object with certain
// fields left unspecified, in which case the caller should use some sane
// defaults.
//
// This function returns an error if it's unable to parse the contents of the
// bootstrap config. It returns (nil, nil) if none of the env vars are set.
func GetConfiguration() (*Config, error) {
fName := envconfig.XDSBootstrapFileName
fContent := envconfig.XDSBootstrapFileContent
if fName != "" {
if logger.V(2) {
logger.Infof("Using bootstrap file with name %q from GRPC_XDS_BOOTSTRAP environment variable", fName)
}
cfg, err := bootstrapFileReadFunc(fName)
if err != nil {
return nil, fmt.Errorf("xds: failed to read bootstrap config from file %q: %v", fName, err)
}
return NewConfigFromContents(cfg)
}
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.View on GitHub (pinned to 03255a9237)
Solutions
- Verify the file exists and is readable: ls -l <path-from-GRPC_XDS_BOOTSTRAP> and run as the same UID.
- If running in Kubernetes, check that the ConfigMap/Secret volume mount and the env var path match exactly.
- Use an absolute path for GRPC_XDS_BOOTSTRAP to avoid working-directory ambiguity.
- Ensure the init container or sidecar that writes the bootstrap file completed successfully before the app container starts.
Example fix
# before: GRPC_XDS_BOOTSTRAP=/etc/grpc-xds/bootstrap.json but file missing # after: mount the config and confirm # kubectl exec <pod> -- ls -l /etc/grpc-xds/bootstrap.json
Defensive patterns
Strategy: validation
Validate before calling
// Verify the bootstrap file is readable before GetConfiguration.
func ensureBootstrapFile(path string) error {
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("bootstrap file %q: %w", path, err)
}
if info.IsDir() {
return fmt.Errorf("bootstrap path %q is a directory", path)
}
return nil
} Try / catch
// Wrap GetConfiguration and report the missing file clearly.
cfg, err := bootstrap.GetConfiguration()
if err != nil {
return fmt.Errorf("cannot load xDS bootstrap from GRPC_XDS_BOOTSTRAP=%q: %w", os.Getenv("GRPC_XDS_BOOTSTRAP"), err)
} Prevention
- Use an absolute path for GRPC_XDS_BOOTSTRAP.
- In Kubernetes, add a startup probe that checks the mounted bootstrap file exists and is non-empty.
- Ensure the init container or sidecar that writes the file runs to completion first.
When it happens
Trigger: Thrown at internal/xds/bootstrap/bootstrap.go:672 when the library encounters an invalid state.
Common situations: Mount path mismatch in Kubernetes (the secret/configmap is mounted at a different path); the env var was set but the file creation step in the init container failed; running locally without copying the bootstrap file into the expected location; wrong relative path interpreted against an unexpected working directory.
Related errors
- 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
- failed to build call credentials from bootstrap for %q: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/842e10107a83f09e.
Report an issue: GitHub.