{"record":{"id":"734345517c193a9d","repo":"ory/hydra","slug":"issuer-url-must-be-set-unless-development-mode-is","errorCode":null,"errorMessage":"issuer URL must be set unless development mode is enabled","messagePattern":"issuer URL must be set unless development mode is enabled","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"driver/config/helper.go","lineNumber":18,"sourceCode":"// Copyright © 2022 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\npackage config\n\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":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/driver/config/helper.go#L1-L35","documentation":"Hydra's Validate() in driver/config requires an issuer URL (config key `urls.issuer`) unless development mode (`dev: true`) is enabled. The issuer URL is the base URL embedded in issued tokens and must be present for OAuth2 to function. Without it (and without dev mode), the server refuses to start.","triggerScenarios":"Calling driver.New() with a DefaultProvider whose IssuerURL() returns an empty string while IsDevelopmentMode() is false — e.g. `urls.issuer` not set in config and no ORY_HYDRA_URLS_ISSUER environment variable provided.","commonSituations":"Fresh Hydra deployments where the operator forgot to set urls.issuer; running the official production Docker image (dev mode off by default) with a minimal config; migrating from dev to production config and dropping the issuer key.","solutions":["Set `urls.issuer` in the Hydra config file, e.g. urls: { issuer: https://my-hydra.example.com }","Set the environment variable SERVE_PUBLIC/... — specifically ORY_HYDRA_URLS_ISSUER=https://my-hydra.example.com","For local development only, start Hydra with `dev: true` (never in production) to bypass the issuer requirement"],"exampleFix":"// before (hydra.yml)\nserve: {}\n// after\nurls:\n  issuer: https://hydra.example.com","handlingStrategy":"validation","validationCode":"func validateIssuer(cfg *hydraConfig) error {\n    if cfg.URLs == nil || cfg.URLs.Issuer == \"\" && !cfg.Dev {\n        return errors.New(\"urls.issuer must be set (or enable dev mode for local testing)\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set urls.issuer in every environment's config, including local","Keep issuer constant per environment — it is embedded in issued tokens","Use a config linter or startup smoke test that calls driver.New in CI"],"tags":["config","oauth2","hydra","startup"],"backgroundTag":"missing-config-key","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"}