cloudflare/cloudflared · error
aud array contains non-string elements
Error message
aud array contains non-string elements
What it means
jwtPayload.UnmarshalJSON accepts an "aud" claim that is either a single string or an array of strings. If the aud value is a JSON array containing any non-string element, unmarshalling fails with this error so malformed tokens are rejected at parse time instead of producing a corrupted Audience field.
Source
Thrown at token/token.go:91
func (p *jwtPayload) UnmarshalJSON(data []byte) error {
type Alias jwtPayload
if err := json.Unmarshal(data, (*Alias)(p)); err != nil {
return err
}
var audParser struct {
Aud any `json:"aud"`
}
if err := json.Unmarshal(data, &audParser); err != nil {
return err
}
switch aud := audParser.Aud.(type) {
case string:
p.Aud = []string{aud}
case []any:
for _, a := range aud {
s, ok := a.(string)
if !ok {
return errors.New("aud array contains non-string elements")
}
p.Aud = append(p.Aud, s)
}
default:
return errors.New("aud field is not a string or an array of strings")
}
return nil
}
func (p jwtPayload) isExpired() bool {
return int(time.Now().Unix()) > p.Exp
}
const (
lockRetryInterval = 2 * time.Second
lockTimeout = 10 * time.Minute
startTimeTolerance = int64(1000) // milliseconds
)View on GitHub (pinned to 2253eeeb25)
Solutions
- Fix the token issuer to emit all aud elements as JSON strings (quote numeric IDs).
- Inspect the offending token's payload (decode base64 JSON) to find the non-string element and correct it at the source.
- If you cannot fix the issuer, pre-validate or rewrite the token payload before passing it to this library.
Example fix
// before (issuer side): "aud": [12345] // after (issuer side): "aud": ["12345"]
Defensive patterns
Strategy: validation
Validate before calling
audVal, ok := payloadMap["aud"].([]any)
if ok {
for _, a := range audVal {
if _, isStr := a.(string); !isStr {
return fmt.Errorf("aud array contains non-string element: %v", a)
}
}
} Type guard
func isStringArray(v any) bool {
arr, ok := v.([]any)
if !ok {
return false
}
for _, a := range arr {
if _, isStr := a.(string); !isStr {
return false
}
}
return true
} Try / catch
p := jwtPayload{}
if err := json.Unmarshal(rawPayload, &p); err != nil {
return fmt.Errorf("malformed JWT payload (check aud claim types): %w", err)
} Prevention
- Ensure token issuers serialize all audience values as JSON strings (quote numeric IDs).
- Decode and inspect token payloads with a JWT debugger before deploying new issuers.
- Add issuer-side contract tests asserting aud is string or []string.
When it happens
Trigger: Unmarshalling a JWT payload (or the metadata JWT header/payload) where aud is an array containing numbers, nulls, booleans, or nested objects, e.g. "aud": ["app", 123] or [null].
Common situations: Token issuers that serialize client IDs as numbers instead of strings, hand-crafted or third-party tokens with heterogeneous aud arrays, or misconfigured identity providers emitting numeric account IDs in the audience claim.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- aud field is not a string or an array of strings
- metadata JWT aud is empty
- failed to determine if token is FED: %w
- metadata JWT auth_domain validation failed: %w
- metadata JWT type %q is not match
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/4ee2c9f9a7e7381a.
Report an issue: GitHub.