ory/kratos · error
configuration value not a valid URL
Error message
configuration value not a valid URL: %s
What it means
Config.ParseAbsoluteOrRelativeURI validates DSN/URI configuration values by parsing them with url.ParseRequestURI. If parsing fails, the underlying parse error is wrapped with this message including the raw value. It means the configuration string is not a syntactically valid absolute or relative URI, so it cannot be used as a connection URL or endpoint.
Solutions
- Inspect the raw value printed in the error and fix or escape invalid characters (percent-encode special characters in passwords using url.QueryEscape).
- Check the environment variable / config file supplying the value for stray whitespace, quotes, or line breaks.
- If a password contains special characters, use the URL-escaped form or reference it via a secret provider instead of inline in the DSN.
- Validate the URI locally with url.ParseRequestURI before injecting it into config to fail fast with a clearer message.
Example fix
// before (unescaped password breaks parsing) dsn: postgres://user:p@ss!word@localhost:5432/kratos // after (percent-encode '@' and '!') dsn: postgres://user:p%40ss%21word@localhost:5432/kratos
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.ParseRequestURI(cfg.DSN)
if err != nil {
return fmt.Errorf("invalid DSN in config: %q: %w", cfg.DSN, err)
} Prevention
- Percent-encode special characters in DSN passwords (url.QueryEscape).
- Lint config files and env vars for stray whitespace/quotes around URLs.
- Validate DSNs at deploy time with url.ParseRequestURI before the service starts.
When it happens
Trigger: Calling (p *Config).ParseAbsoluteOrRelativeURI(rawUrl) where rawUrl fails url.ParseRequestURI — e.g. DSN values containing characters invalid in a URI (spaces, unescaped '%', stray quotes), values like 'host:=pass@host/db' with illegal characters, or typos such as missing scheme entirely when an absolute URL is required.
Common situations: Secrets/DSNs set via environment variables or config files contain shell-interpolated characters, spaces from copy-paste, unescaped special characters in passwords (e.g. '@', '#', '%' not percent-encoded), or the value is empty/garbled from a templating mistake.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- configuration value is not a valid URL
- you must provide `secrets.pagination` for FIPS compliance
- expected to get the DSN as an argument, or the…
- required config value "dsn" was not set
- you must provide `secrets.cipher` for FIPS compliance
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/c7948d81caa16ef3.
Report an issue: GitHub.
Appendix: source
Thrown at driver/config/config.go:1317
Fatalf("Configuration value from key %s is not a valid URL: %s", key, p.GetProvider(ctx).String(key))
}
return parsed
}
func (p *Config) ParseURIOrFail(ctx context.Context, key string) *url.URL {
parsed, err := p.ParseURI(p.GetProvider(ctx).String(key))
if err != nil {
p.l.WithField("reason", "expected scheme to be set").
Fatalf("Configuration value from key %s is not a valid URL: %s", key, p.GetProvider(ctx).String(key))
}
return parsed
}
func (p *Config) ParseAbsoluteOrRelativeURI(rawUrl string) (*url.URL, error) {
u, frag := splitUrlAndFragment(rawUrl)
parsed, err := url.ParseRequestURI(u)
if err != nil {
return nil, errors.Wrapf(err, "configuration value not a valid URL: %s", rawUrl)
}
if frag != "" {
parsed.Fragment = frag
}
return parsed, nil
}
func (p *Config) ParseURI(rawUrl string) (*url.URL, error) {
parsed, err := p.ParseAbsoluteOrRelativeURI(rawUrl)
if err != nil {
return nil, err
}
if parsed.Scheme == "" {
return nil, errors.Errorf("configuration value is not a valid URL: %s", rawUrl)
}
return parsed, nilView on GitHub (pinned to b86338da04)