{"record":{"id":"b1272c826c48ee72","repo":"ory/kratos","slug":"configuration-value-is-not-a-valid-url-s","errorCode":null,"errorMessage":"configuration value is not a valid URL: %s","messagePattern":"configuration value is not a valid URL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"driver/config/config.go","lineNumber":1333,"sourceCode":"\tparsed, err := url.ParseRequestURI(u)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"configuration value not a valid URL: %s\", rawUrl)\n\t}\n\n\tif frag != \"\" {\n\t\tparsed.Fragment = frag\n\t}\n\n\treturn parsed, nil\n}\n\nfunc (p *Config) ParseURI(rawUrl string) (*url.URL, error) {\n\tparsed, err := p.ParseAbsoluteOrRelativeURI(rawUrl)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif parsed.Scheme == \"\" {\n\t\treturn nil, errors.Errorf(\"configuration value is not a valid URL: %s\", rawUrl)\n\t}\n\treturn parsed, nil\n}\n\nfunc (p *Config) Tracing(ctx context.Context) *otelx.Config {\n\treturn p.GetProvider(ctx).TracingConfig(\"Ory Kratos\")\n}\n\nfunc (p *Config) IsInsecureDevMode(ctx context.Context) bool {\n\treturn p.GetProvider(ctx).Bool(\"dev\")\n}\n\nfunc (p *Config) IsBackgroundCourierEnabled(ctx context.Context) bool {\n\treturn p.GetProvider(ctx).Bool(\"watch-courier\")\n}\n\nfunc (p *Config) CourierExposeMetricsPort(ctx context.Context) int {\n\treturn p.GetProvider(ctx).Int(\"expose-metrics-port\")","sourceCodeStart":1315,"sourceCodeEnd":1351,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/driver/config/config.go#L1315-L1351","documentation":"Config.ParseURI delegates to ParseAbsoluteOrRelativeURI and then additionally requires the parsed URL to have a non-empty scheme. If the value parses as a URI but has no scheme (e.g. 'localhost:5432/db' or a bare path), this error is thrown because the library needs an absolute URL with an explicit scheme to know which driver/protocol to use.","triggerScenarios":"Calling (p *Config).ParseURI(rawUrl) where rawUrl passes URI parsing but parsed.Scheme == \"\" — e.g. dsn set to 'localhost:5432/db?sslmode=disable' or 'mydb.sqlite' without a 'sqlite://' prefix, or a DSN that lost its 'postgres://' prefix.","commonSituations":"Migrating from a driver that accepted bare host strings, config templates where the scheme portion was accidentally deleted, or users writing 'sqlite:./db.sqlite' variants the parser treats as scheme-less.","solutions":["Add the correct scheme to the configured URL, e.g. 'postgres://host/db', 'mysql://host/db', or 'sqlite://file?mode=rwc'.","Check env var or YAML for a lost 'scheme://' prefix after templating or secret substitution.","Consult the driver docs for the exact accepted DSN format and copy a known-good example.","Pre-validate the value with url.Parse and check u.Scheme != \"\" before setting it in config."],"exampleFix":"// before\nDSN=postgres://\nDSN=localhost:5432/kratos\n\n// after\nDSN=postgres://localhost:5432/kratos?sslmode=disable","handlingStrategy":"validation","validationCode":"u, err := url.ParseRequestURI(cfg.DSN)\nif err != nil {\n    return err\n}\nif u.Scheme == \"\" {\n    return fmt.Errorf(\"DSN %q must include a scheme (e.g. postgres://)\", cfg.DSN)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write DSNs with an explicit scheme prefix (postgres://, mysql://, sqlite://).","Add a config linter/schema check asserting the dsn field parses with a non-empty scheme.","When templating DSNs, guard the scheme portion separately from the host part."],"tags":["config","url","scheme","validation"],"backgroundTag":"invalid-url-format","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}