grpc/grpc-go · error
required field SubjectTokenType is not specified
Error message
required field SubjectTokenType is not specified
What it means
Returned by sts.validateOptions (credentials/sts/sts.go:227) when opts.SubjectTokenType is empty. SubjectTokenType is the RFC 8693 token-type identifier (e.g. urn:ietf:params:oauth:token-type:jwt) telling the STS server how to interpret the contents of the subject token file; it is Required in the Options struct (line 101). validateOptions enforces ordering — URI checked first, then SubjectTokenPath, then SubjectTokenType.
Source
Thrown at credentials/sts/sts.go:227
// - 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.tokenMetadata
}
return nil
}View on GitHub (pinned to 03255a9237)
Solutions
- Set Options.SubjectTokenType to the correct RFC 8693 URN for your token (commonly urn:ietf:params:oauth:token-type:jwt or urn:ietf:params:oauth:token-type:access_token).
- Confirm the type matches the actual contents of the file at SubjectTokenPath.
- Validate the whole Options struct up front and fail startup on any empty required field.
Example fix
// before
c, _ := sts.NewCredentials(sts.Options{
TokenExchangeServiceURI: "https://sts.googleapis.com/v1/token",
SubjectTokenPath: "/var/run/secrets/subject-token",
}) // SubjectTokenType missing
// after
c, err := sts.NewCredentials(sts.Options{
TokenExchangeServiceURI: "https://sts.googleapis.com/v1/token",
SubjectTokenPath: "/var/run/secrets/subject-token",
SubjectTokenType: "urn:ietf:params:oauth:token-type:jwt",
}) Defensive patterns
Strategy: validation
Validate before calling
// Ensure a non-empty, well-formed token type URN.
var knownTokenTypes = map[string]bool{
"urn:ietf:params:oauth:token-type:jwt": true,
"urn:ietf:params:oauth:token-type:access_token": true,
"urn:ietf:params:oauth:token-type:id_token": true,
"urn:ietf:params:oauth:token-type:saml2": true,
}
if opts.SubjectTokenType == "" || !knownTokenTypes[opts.SubjectTokenType] {
return fmt.Errorf("SubjectTokenType %q unknown/empty", opts.SubjectTokenType)
} Try / catch
c, err := sts.NewCredentials(opts)
if err != nil { log.Fatalf("STS creds: %v", err) } Prevention
- Document the allowed token-type URNs in your config template.
- Validate the URN against an allow-list so typos fail fast.
When it happens
Trigger: Calling sts.NewCredentials with SubjectTokenType unset or empty. Because validateOptions checks SubjectTokenPath before SubjectTokenType, you only see this error once SubjectTokenPath is already set.
Common situations: Forgetting the token-type URN (it is long and easy to omit); copy-pasting an Options literal that left it blank; using a wrong key name in JSON config so the field stays zero-value.
Related errors
- empty token_exchange_service_uri in options
- required field SubjectTokenPath is not specified
- missing fallback credentials
- token file access error
- pemfile: certificate and key file must be in the same direct
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/4460e3179dd2285d.
Report an issue: GitHub.