{"record":{"id":"2f0330d9c41773c5","repo":"ory/hydra","slug":"issuer-url-scheme-must-be-https-unless-development","errorCode":null,"errorMessage":"issuer URL scheme must be HTTPS unless development mode is enabled","messagePattern":"issuer URL scheme must be HTTPS unless development mode is enabled","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"driver/config/helper.go","lineNumber":23,"sourceCode":"\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/ory/x/logrusx\"\n)\n\nfunc Validate(ctx context.Context, l *logrusx.Logger, p *DefaultProvider) error {\n\tif p.IssuerURL(ctx).String() == \"\" && !p.IsDevelopmentMode(ctx) {\n\t\tl.Errorf(\"Configuration key `%s` must be set `dev` is `false`. To find out more, use `hydra help serve`.\", KeyIssuerURL)\n\t\treturn errors.New(\"issuer URL must be set unless development mode is enabled\")\n\t}\n\n\tif p.IssuerURL(ctx).Scheme != \"https\" && !p.IsDevelopmentMode(ctx) {\n\t\tl.Errorf(\"Scheme from configuration key `%s` must be `https` when `dev` is `false`. Got scheme in value `%s` is `%s`. To find out more, use `hydra help serve`.\", KeyIssuerURL, p.IssuerURL(ctx).String(), p.IssuerURL(ctx).Scheme)\n\t\treturn errors.New(\"issuer URL scheme must be HTTPS unless development mode is enabled\")\n\t}\n\n\treturn nil\n}\n\nfunc urlRoot(u *url.URL) *url.URL {\n\tif u.Path == \"\" {\n\t\tu.Path = \"/\"\n\t}\n\treturn u\n}\n","sourceCodeStart":5,"sourceCodeEnd":35,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/driver/config/helper.go#L5-L35","documentation":"Hydra's Validate() enforces that the issuer URL uses the HTTPS scheme unless development mode is enabled. The issuer is embedded in tokens and exposed publicly, so plain HTTP is rejected to prevent token-issuer spoofing and insecure transport.","triggerScenarios":"Calling driver.New() where p.IssuerURL(ctx).Scheme != \"https\" (e.g. `urls.issuer: http://hydra.example.com`) while IsDevelopmentMode() is false.","commonSituations":"Pointing urls.issuer at http:// behind a TLS-terminating load balancer; using localhost http URLs copied from a dev setup into production; misconfigured reverse proxy meaning the issuer is http while the public endpoint is https.","solutions":["Change urls.issuer to use the https:// scheme, e.g. https://hydra.example.com","Set ORY_HYDRA_URLS_ISSUER to an https:// URL","For local development only, enable `dev: true` to allow http issuers"],"exampleFix":"// before\nurls:\n  issuer: http://hydra.example.com\n// after\nurls:\n  issuer: https://hydra.example.com","handlingStrategy":"validation","validationCode":"func validateIssuerScheme(issuer string) error {\n    u, err := url.Parse(issuer)\n    if err != nil {\n        return err\n    }\n    if u.Scheme != \"https\" {\n        return fmt.Errorf(\"issuer %q must use https\", issuer)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only ever configure https:// issuer URLs outside local dev","Never relax with dev:true to work around prod config","Terminate TLS at the proxy but keep the issuer URL https://"],"tags":["config","https","tls","oauth2"],"backgroundTag":"insecure-scheme-rejected","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}