ory/kratos · error
could not create request
Error message
could not create request: %w
What it means
For file and base64 schemes ReadSchema falls through to fetching the schema over HTTP via retryablehttp. If the HTTP request itself cannot be constructed (malformed URL parsed by NewRequestWithContext), it returns "could not create request". This precedes any network I/O, so it indicates an invalid URI string rather than a server problem.
Solutions
- Validate the schema URL parses (url.Parse) and uses http or https
- Quote the URI in YAML/config and check for stray spaces or newline characters
- Fix the scheme spelling (http:// or https://)
- Verify env substitution yields the full intended URL, not an empty string
Example fix
// before identity_schemas: default: htp://localhost:4455/schemas/default.json // after identity_schemas: default: http://localhost:4455/schemas/default.json
Defensive patterns
Strategy: validation
Validate before calling
// Go: preflight an http(s) schema URI
func schemaURIFetchable(raw string) error {
u, err := url.Parse(raw)
if err != nil {
return fmt.Errorf("schema URI does not parse: %w", err)
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("unsupported scheme %q; use http(s)", u.Scheme)
}
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
if err != nil {
return fmt.Errorf("invalid schema request URL: %w", err)
}
_ = req
return nil
} Type guard
func isParseableURL(raw string) bool {
_, err := url.Parse(raw)
return err == nil
} Try / catch
schema, err := h.ReadSchema(ctx, uri)
if err != nil {
if strings.Contains(err.Error(), "could not create request") {
return fmt.Errorf("malformed schema URL %q — check scheme and characters", uri)
}
return err
} Prevention
- Quote schema URLs in YAML to prevent shell/interpolation corruption
- url.Parse the URI in a startup preflight
- Verify env substitution resolves to a complete URL
- Watch for hidden whitespace/newlines when pasting URLs from docs
When it happens
Trigger: Identity schema URI with an unsupported/invalid scheme or malformed URL — e.g. "ftp://host/s.json", "http://[bad-ipv6", spaces or control characters in the URL — that retryablehttp.NewRequestWithContext rejects.
Common situations: Unquoted config value where shell/interpolation characters corrupt the URL; typos in the scheme (htp://); env var templating producing an empty or malformed URI; copied URL containing trailing whitespace or hidden characters.
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
- could not read schema file
- could not decode schema file
- no credentials found
- failed to unmarshal webhook configuration for
- failed to unmarshal notify_previous_addresses configuration…
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/acb8d60315de1063.
Report an issue: GitHub.
Appendix: source
Thrown at schema/handler.go:246
func (h *Handler) ReadSchema(ctx context.Context, uri *url.URL) (data []byte, err error) {
ctx, span := h.r.Tracer(ctx).Tracer().Start(ctx, "schema.Handler.ReadSchema")
defer otelx.End(span, &err)
switch uri.Scheme {
case "file":
data, err = os.ReadFile(uri.Host + uri.Path) //nolint:gosec
if err != nil {
return nil, errors.WithStack(fmt.Errorf("could not read schema file: %w", err))
}
case "base64":
data, err = base64.StdEncoding.DecodeString(strings.TrimPrefix(uri.String(), "base64://"))
if err != nil {
return nil, errors.WithStack(fmt.Errorf("could not decode schema file: %w", err))
}
default:
req, err := retryablehttp.NewRequestWithContext(ctx, http.MethodGet, uri.String(), nil)
if err != nil {
return nil, errors.WithStack(fmt.Errorf("could not create request: %w", err))
}
resp, err := h.r.HTTPClient(ctx).Do(req)
if err != nil {
return nil, errors.WithStack(herodot.ErrUpstreamError().WithReason("could not fetch schema").WithError(err.Error()).WithDetail("uri", uri))
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusNotFound {
return nil, herodot.ErrNotFound().WithDetail("url", uri)
}
return nil, errors.WithStack(herodot.ErrUpstreamError().WithError("upstream error").WithDetail("status_code", resp.StatusCode).WithDetail("uri", uri))
}
data, err = io.ReadAll(io.LimitReader(resp.Body, maxSchemaSize))
if err != nil {
return nil, errors.WithStack(herodot.ErrUpstreamError().WithReason("could not read schema response").WithError(err.Error()).WithDetail("uri", uri))
}
}
return data, nilView on GitHub (pinned to b86338da04)