grpc/grpc-go · error
empty accessToken in response (%v)
Error message
empty accessToken in response (%v)
What it means
Returned by tokenInfoFromResponse in sts/sts.go:329 when the STS response parsed as valid JSON but the access_token field is empty. Per RFC 8693 the issued_token/access_token is REQUIRED, so gRPC treats an empty value as a protocol violation even on HTTP 200.
Source
Thrown at credentials/sts/sts.go:329
resp.Body.Close()
if err != nil {
return nil, err
}
if resp.StatusCode == http.StatusOK {
return body, nil
}
logger.Warningf("http status %d, body: %s", resp.StatusCode, string(body))
return nil, fmt.Errorf("http status %d, body: %s", resp.StatusCode, string(body))
}
func tokenInfoFromResponse(respBody []byte) (*tokenInfo, error) {
respData := &responseParameters{}
if err := json.Unmarshal(respBody, respData); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%v): %v", respBody, err)
}
if respData.AccessToken == "" {
return nil, fmt.Errorf("empty accessToken in response (%v)", string(respBody))
}
return &tokenInfo{
tokenType: respData.TokenType,
token: respData.AccessToken,
expiryTime: time.Now().Add(time.Duration(respData.ExpiresIn) * time.Second),
}, nil
}
// requestParameters stores all STS request attributes defined in
// https://tools.ietf.org/html/rfc8693#section-2.1.
type requestParameters struct {
// REQUIRED. The value "urn:ietf:params:oauth:grant-type:token-exchange"
// indicates that a token exchange is being performed.
GrantType string `json:"grant_type"`
// OPTIONAL. Indicates the location of the target service or resource where
// the client intends to use the requested security token.
Resource string `json:"resource,omitempty"`
// OPTIONAL. The logical name of the target service where the client intendsView on GitHub (pinned to 03255a9237)
Solutions
- Inspect the response body shown in the error to see which fields were returned.
- Verify SubjectTokenType is a type the STS server can actually exchange for an access token.
- Confirm RequestedTokenType and Audience are supported by the issuer.
- Check the STS server logs / contact the token broker owner if 200-with-empty-token persists.
Example fix
// before
opts := sts.Options{
SubjectTokenType: "urn:ietf:params:oauth:token-type:unknown",
}
// after
opts := sts.Options{
SubjectTokenType: "urn:ietf:params:oauth:token-type:jwt",
RequestedTokenType: "urn:ietf:params:oauth:token-type:access_token",
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure requested/subject token types are ones the issuer will exchange for an access token.
// Validate config before dial; the only runtime guard is parsing the error.
if opts.SubjectTokenType == "" { return errors.New("SubjectTokenType required") }
if opts.RequestedTokenType != "" && opts.RequestedTokenType != "urn:ietf:params:oauth:token-type:access_token" {
return fmt.Errorf("unsupported requested token type %q", opts.RequestedTokenType)
} Try / catch
if strings.Contains(err.Error(), "empty accessToken in response") {
// issuer returned 200 with no access_token; verify SubjectTokenType/Audience/RequestedTokenType
} Prevention
- Use standard RFC 8693 token-type URNs for SubjectTokenType and RequestedTokenType.
- Confirm Audience matches a value the STS server can mint for.
- Log the full response body when this fires to diagnose server-side issuance skips.
When it happens
Trigger: The STS server returns 200 with a JSON body missing the access_token field (or an empty string), e.g. returns only issued_token_type/token_type, or an error-shaped JSON that nonetheless carried 200.
Common situations: Subject/actor token accepted but no token issued (rare server bug); audience/scope accepted structurally but issuance skipped; STS implementation that returns 200 with an error payload; subject token type not actually exchangeable.
Related errors
- http status %d, body: %s
- failed to create http request: %v
- unable to transfer STS PerRPCCredentials: %v
- scheme is not supported: %q. Only http(s) is supported
- json.Unmarshal(%v): %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/30bb7e38a5634f93.
Report an issue: GitHub.