semaphoreui/semaphore · error
internal error
Error message
internal error
What it means
GetJWKS serves the JSON Web Key Set used to verify JWTs issued by Semaphore. It calls signer.JWKS() to marshal the signing keys to JWKSet JSON; if that marshaling fails, the endpoint logs the underlying error and returns HTTP 500 'internal error' instead of a key set. This indicates an internal problem generating/serializing the key set, not a client mistake.
Solutions
- Check server logs for the 'failed to marshal JWKS' entry with the underlying error to identify the key problem
- Verify the JWT signing key configuration/secret in Semaphore's config is valid and accessible
- Regenerate or re-provision the signing key and restart the server
- If a custom signer is used, fix its JWKS() implementation
Defensive patterns
Strategy: try-catch
Validate before calling
// client can only detect failure:
resp, err := http.Get(baseURL + "/api/jwks")
if err == nil && resp.StatusCode == http.StatusInternalServerError { /* JWKS unavailable: check server key config */ } Try / catch
resp, err := http.Get(baseURL + "/api/jwks")
if err != nil { return err }
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("jwks endpoint returned %d; check server signing key config", resp.StatusCode)
} Prevention
- Monitor server logs for 'failed to marshal JWKS'
- Provision valid, readable JWT signing keys before startup
- Test /api/jwks as a health check after key rotation
- Keep key material format compatible with the signer implementation
When it happens
Trigger: GET /api/jwks (public endpoint) when c.signer.JWKS() returns an error — i.e. the underlying crypto signer cannot produce or marshal its public key set (e.g. corrupted/missing key material in the signer).
Common situations: Misconfigured or corrupt JWT signing key store; key loaded from an incompatible source so the public key cannot be exported to JWK format; custom signer implementations returning errors from JWKS(); failures right after key rotation or when running multiple replicas with inconsistent key storage.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Unauthorized
- Account linking must be initiated with a POST request.
- You must be signed in to link an external account.
- OIDC sign-in failed: state cookie is missing. Try signing…
- OIDC sign-in failed: invalid state. Try signing in again.
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/1de94fdbccdf907c.
Report an issue: GitHub.
Appendix: source
Thrown at api/jwks.go:34
return &JwksController{signer: signer}
}
// GetJWKS serves the JSON Web Key Set.
func (c *JwksController) GetJWKS(w http.ResponseWriter, _ *http.Request) {
if util.Config == nil || util.Config.JWT == nil || !util.Config.JWT.Enabled {
http.NotFound(w, nil)
return
}
if c.signer == nil {
http.NotFound(w, nil)
return
}
body, err := c.signer.JWKS()
if err != nil {
log.WithError(err).WithField("context", "jwt").Error("failed to marshal JWKS")
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write(body)
}
View on GitHub (pinned to 1774ccb71a)