cloudflare/cloudflared · error
failed to marshal signPayload
Error message
failed to marshal signPayload
What it means
After extracting JWT claims, SignCert marshals a signPayload struct (public key, JWT, issuer) to JSON to POST to the token issuer's sign endpoint. This error means json.Marshal failed on that struct, which is essentially impossible for plain string fields and usually indicates a programming-level problem (nil dereference via bad input types) rather than user input.
Source
Thrown at sshgen/sshgen.go:110
parsedToken, err := jwt.ParseSigned(token, signatureAlgs)
if err != nil {
return "", errors.Wrap(err, "failed to parse JWT")
}
claims := jwt.Claims{}
err = parsedToken.UnsafeClaimsWithoutVerification(&claims)
if err != nil {
return "", errors.Wrap(err, "failed to retrieve JWT claims")
}
buf, err := json.Marshal(&signPayload{
PublicKey: pubKey,
JWT: token,
Issuer: claims.Issuer,
})
if err != nil {
return "", errors.Wrap(err, "failed to marshal signPayload")
}
var res *http.Response
if mockRequest != nil {
res, err = mockRequest(claims.Issuer+signEndpoint, "application/json", bytes.NewBuffer(buf))
} else {
client := http.Client{
Timeout: 10 * time.Second,
}
res, err = client.Post(claims.Issuer+signEndpoint, "application/json", bytes.NewBuffer(buf))
}
if err != nil {
return "", errors.Wrap(err, "failed to send request")
}
defer res.Body.Close()
decoder := json.NewDecoder(res.Body)
View on GitHub (pinned to 2253eeeb25)
Solutions
- Confirm signPayload fields are JSON-encodable strings or pointers
- Log the underlying wrapped error to identify the offending field
- If this appears, it is a code bug — fix the signPayload definition rather than retrying
- Add a unit test marshaling a representative signPayload
Example fix
// before
buf, err := json.Marshal(&signPayload{PublicKey: pubKey, JWT: token, Issuer: claims.Issuer})
if err != nil {
return "", errors.Wrap(err, "failed to marshal signPayload")
}
// after
payload := signPayload{PublicKey: pubKey, JWT: token, Issuer: claims.Issuer}
buf, err := json.Marshal(&payload)
if err != nil {
return "", errors.Wrap(err, fmt.Sprintf("failed to marshal signPayload: unsupported value in %T", payload))
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure payload is encodable before the call
if _, err := json.Marshal(signPayload{PublicKey: pubKey, JWT: token, Issuer: issuer}); err != nil {
return fmt.Errorf("payload not encodable: %w", err)
} Try / catch
if _, err := SignCert(token, pubKey); err != nil {
if strings.Contains(err.Error(), "failed to marshal signPayload") {
return fmt.Errorf("internal encoding bug: %w", err)
}
} Prevention
- Keep signPayload fields to JSON-encodable types (string, []byte) only
- Add a unit test that marshals a representative payload
- Treat this error as a code bug, not a runtime condition
When it happens
Trigger: json.Marshal of the signPayload struct returns an error — practically only when a field holds an unsupported value such as a channel, func, or cyclic value; with current string fields this is effectively dead defensive code.
Common situations: Recompiling sshgen with modified signPayload field types that json cannot encode; extremely rare in normal operation.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- failed to serialize json body
- Unable to marshal tunnel credentials to JSON
- failed to decode HTTP response
- unable to unmarshal LogEventType string
- unable to unmarshal LogEventType
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/94a4090a406fcf4e.
Report an issue: GitHub.