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

  1. Check server logs for the 'failed to marshal JWKS' entry with the underlying error to identify the key problem
  2. Verify the JWT signing key configuration/secret in Semaphore's config is valid and accessible
  3. Regenerate or re-provision the signing key and restart the server
  4. 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

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


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)