grpc/grpc-go · critical

failed to build call credentials from bootstrap for %q: %v

Error message

failed to build call credentials from bootstrap for %q: %v

What it means

Returned by ServerConfig.UnmarshalJSON (internal/xds/bootstrap/bootstrap.go:390) when building a call-credentials configuration fails. This path only runs when GRPC_XDS_BOOTSTRAP_CALL_CREDS (envconfig.XDSBootstrapCallCredsEnabled) is enabled; for each supported call-creds type, Build() is invoked and the first failure is fatal.

Source

Thrown at internal/xds/bootstrap/bootstrap.go:391

			sc.extraDialOptions = d.DialOptions()
		}
		sc.cleanups = append(sc.cleanups, cancel)
		break
	}

	if envconfig.XDSBootstrapCallCredsEnabled {
		// Process call credentials - unlike channel creds, we use ALL supported
		// types. Also, call credentials are optional as per gRFC A97.
		for _, cfg := range server.CallCredsConfigs {
			c := bootstrap.GetCallCredentials(cfg.Type)
			if c == nil {
				// Skip unsupported call credential types (don't fail bootstrap).
				continue
			}
			callCreds, cancel, err := c.Build(cfg.Config)
			if err != nil {
				// Call credential validation failed - this should fail bootstrap.
				return fmt.Errorf("failed to build call credentials from bootstrap for %q: %v", cfg.Type, err)
			}
			sc.selectedCallCreds = append(sc.selectedCallCreds, callCreds)
			sc.extraDialOptions = append(sc.extraDialOptions, grpc.WithPerRPCCredentials(callCreds))
			sc.cleanups = append(sc.cleanups, cancel)
		}
	}

	if sc.serverURI == "" {
		return fmt.Errorf("xds: `server_uri` field in server config cannot be empty: %s", string(data))
	}
	if sc.credsDialOption == nil {
		return fmt.Errorf("xds: `channel_creds` field in server config cannot be empty: %s", string(data))
	}
	return nil
}

// ServerConfigTestingOptions specifies options for creating a new ServerConfig
// for testing purposes.

View on GitHub (pinned to 03255a9237)

Solutions

  1. Read the wrapped error (%v) to see why the call-creds Build failed
  2. Fix the call_creds config (correct token path, valid ADC, right plugin config)
  3. Disable GRPC_XDS_BOOTSTRAP_CALL_CREDS if call creds to the management server are not required

Example fix

// before: token file creds type with bad path
{"call_creds":[{"type":"token_file","config":{"token_path":"/missing/token"}}]}
// after
{"call_creds":[{"type":"token_file","config":{"token_path":"/etc/secrets/xds.token"}}]}
Defensive patterns

Strategy: validation

Validate before calling

// If call creds are enabled, verify their sources resolve first.
if os.Getenv("GRPC_XDS_BOOTSTRAP_CALL_CREDS") != "" {
    for _, cc := range serverCallCreds {
        if cc.Type == "token_file" {
            var cfg struct{ Path string `json:"token_path"` }
            _ = json.Unmarshal(cc.Config, &cfg)
            if _, err := os.Stat(cfg.Path); err != nil { return err }
        }
    }
}

Try / catch

cfg, err := bootstrap.NewConfigFromContents(data)
if err != nil {
    if strings.Contains(err.Error(), "call credentials") {
        log.Fatalf("bootstrap call creds failed to build: %v", err)
    }
}

Prevention

When it happens

Trigger: XDSBootstrapCallCredsEnabled is true and a `call_creds` entry of a supported type fails to build — e.g. a token-file/OAuth creds plugin that cannot read its source, or a service-account config that is invalid.

Common situations: Enabling call creds for the management server but pointing at an unreadable token file; ADC unavailable for the call-creds type; plugin config schema mismatch.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/ef7a547458024ead. Report an issue: GitHub.