grpc/grpc-go · error
required field SubjectTokenPath is not specified
Error message
required field SubjectTokenPath is not specified
What it means
Returned by sts.validateOptions when Options.SubjectTokenPath is empty. The subject token is the security token (e.g., a Kubernetes service-account JWT or a VM identity token) that the STS client exchanges for an access token; without a file path to read it from, the token exchange cannot be constructed.
Solutions
- Set Options.SubjectTokenPath to the filesystem path of the subject token file (e.g., /var/run/secrets/tokens/token).
- Confirm the file is readable by the process before creating the credentials.
- If the path is templated from config, validate the template resolved to a non-empty value.
Example fix
// before
opts := sts.Options{
TokenExchangeServiceURI: "https://sts.googleapis.com/v1/token",
// SubjectTokenPath missing
}
// after
opts := sts.Options{
TokenExchangeServiceURI: "https://sts.googleapis.com/v1/token",
SubjectTokenPath: "/var/run/secrets/tokens/sa-token",
} Defensive patterns
Strategy: validation
Validate before calling
if opts.SubjectTokenPath == "" {
return fmt.Errorf("SubjectTokenPath must be set to a readable token file")
}
if _, err := os.Stat(opts.SubjectTokenPath); err != nil {
return fmt.Errorf("subject token file not accessible: %w", err)
} Prevention
- Set SubjectTokenPath to the path of the subject token file.
- Verify the file is readable at startup.
- For workload identity, confirm the token injection path matches the configured value.
When it happens
Trigger: Calling sts.NewCredentials with an Options struct where SubjectTokenPath is not set (empty string). This is a required field validated after the TokenExchangeServiceURI check.
Common situations: Config files that map STS options from bootstrap data but omit the subject_token_path key. Workload-identity setups where the path is supposed to be injected by the runtime but the injection failed or the key name changed between versions.
Related errors
- empty token_exchange_service_uri in options
- required field SubjectTokenType is not specified
- missing fallback credentials
- AuthInfo is nil
- cannot have a leading slash
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/2a666df32e4d54d7.
Report an issue: GitHub.
Appendix: source
Thrown at credentials/sts/sts.go:231
// validateOptions performs the following validation checks on opts:
// - tokenExchangeServiceURI is not empty
// - tokenExchangeServiceURI is a valid URI with a http(s) scheme
// - subjectTokenPath and subjectTokenType are not empty.
func validateOptions(opts Options) error {
if opts.TokenExchangeServiceURI == "" {
return errors.New("empty token_exchange_service_uri in options")
}
u, err := url.Parse(opts.TokenExchangeServiceURI)
if err != nil {
return err
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("scheme is not supported: %q. Only http(s) is supported", u.Scheme)
}
if opts.SubjectTokenPath == "" {
return errors.New("required field SubjectTokenPath is not specified")
}
if opts.SubjectTokenType == "" {
return errors.New("required field SubjectTokenType is not specified")
}
return nil
}
// cachedMetadata returns the cached metadata provided it is not going to
// expire anytime soon.
//
// Caller must hold c.mu.
func (c *callCreds) cachedMetadata() map[string]string {
now := time.Now()
// If the cached token has not expired and the lifetime remaining on that
// token is greater than the minimum value we are willing to accept, go
// ahead and use it.
if c.tokenExpiry.After(now) && c.tokenExpiry.Sub(now) > minCachedTokenLifetime {
return c.tokenMetadataView on GitHub (pinned to 0c51461d27)