grpc/grpc-go · error
xds: failed to read bootstrap config from file
Error message
xds: failed to read bootstrap config from file %q: %v
What it means
Returned by GetConfiguration when os.ReadFile of the bootstrap file path fails. The path comes from GRPC_XDS_BOOTSTRAP (or the envconfig override). The underlying OS error (not exist, permission denied, etc.) is wrapped.
Solutions
- Confirm GRPC_XDS_BOOTSTRAP is set and the path exists: ls -l $GRPC_XDS_BOOTSTRAP.
- In containers/k8s, ensure the ConfigMap/secret holding the bootstrap is mounted at that path.
- Check read permissions for the process's UID/GID.
- Use an absolute path to avoid working-directory ambiguity.
Example fix
# before export GRPC_XDS_BOOTSTRAP=/etc/grpc-bootstrap.json # file absent # after export GRPC_XDS_BOOTSTRAP=/etc/grpc-xds/bootstrap.json ls -l /etc/grpc-xds/bootstrap.json
Defensive patterns
Strategy: validation
Validate before calling
// Startup readiness check for the bootstrap file.
func checkBootstrapFile(path string) error {
fi, err := os.Stat(path)
if err != nil {
return fmt.Errorf("bootstrap file: %w", err)
}
if fi.Size() == 0 {
return fmt.Errorf("bootstrap file is empty")
}
return nil
} Try / catch
if _, err := bootstrap.GetConfiguration(); err != nil {
if strings.Contains(err.Error(), "failed to read bootstrap config from file") {
// fix GRPC_XDS_BOOTSTRAP path/permissions, then restart.
}
} Prevention
- Set GRPC_XDS_BOOTSTRAP to an absolute path.
- Mount the bootstrap file as a ConfigMap/secret in k8s.
- Add a container startup probe that stat()s the file.
When it happens
Trigger: Triggered at bootstrap.go:672 when bootstrapFileReadFunc(fName) (os.ReadFile) errors. The file does not exist, is not readable, or the path is wrong.
Common situations: GRPC_XDS_BOOTSTRAP points to a missing path; in a container the bootstrap file was not mounted/copied; file permissions deny the process; relative path resolved against an unexpected working directory.
Related errors
- failed to build credentials bundle from bootstrap for
- missing server_listener_resource_name_template in the…
- xds: `channel_creds` field in server config cannot be empty
- xds: config parsing for certificate provider plugin
- xds: error normalizing JSON bootstrap configuration
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/842e10107a83f09e.
Report an issue: GitHub.
Appendix: 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 0c51461d27)