{"record":{"id":"1de94fdbccdf907c","repo":"semaphoreui/semaphore","slug":"internal-error","errorCode":null,"errorMessage":"internal error","messagePattern":"internal error","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"api/jwks.go","lineNumber":34,"sourceCode":"\treturn &JwksController{signer: signer}\n}\n\n// GetJWKS serves the JSON Web Key Set.\nfunc (c *JwksController) GetJWKS(w http.ResponseWriter, _ *http.Request) {\n\tif util.Config == nil || util.Config.JWT == nil || !util.Config.JWT.Enabled {\n\t\thttp.NotFound(w, nil)\n\t\treturn\n\t}\n\n\tif c.signer == nil {\n\t\thttp.NotFound(w, nil)\n\t\treturn\n\t}\n\n\tbody, err := c.signer.JWKS()\n\tif err != nil {\n\t\tlog.WithError(err).WithField(\"context\", \"jwt\").Error(\"failed to marshal JWKS\")\n\t\thttp.Error(w, \"internal error\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\t_, _ = w.Write(body)\n}\n","sourceCodeStart":16,"sourceCodeEnd":41,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/api/jwks.go#L16-L41","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// client can only detect failure:\nresp, err := http.Get(baseURL + \"/api/jwks\")\nif err == nil && resp.StatusCode == http.StatusInternalServerError { /* JWKS unavailable: check server key config */ }","typeGuard":null,"tryCatchPattern":"resp, err := http.Get(baseURL + \"/api/jwks\")\nif err != nil { return err }\nif resp.StatusCode != http.StatusOK {\n    return fmt.Errorf(\"jwks endpoint returned %d; check server signing key config\", resp.StatusCode)\n}","preventionTips":["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"],"tags":["http","jwt","jwks","internal-error"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}