ory/hydra · error
Failed to create request: %s
Error message
Failed to create request: %s
What it means
Returned when http.NewRequestWithContext fails to construct the PUT request to the Hydra admin device-accept URL. NewRequestWithContext only errors on an invalid method or an unparseable URL, so this almost always means acceptURL is malformed. The handler responds with a 500 containing the parse error.
Source
Thrown at cmd/cmd_perform_device_flow.go:206
// Accept the user code with a hand-rolled request instead of the generated
// client: other modules in this repository compile this package against the
// released hydra-client-go/v2 module, which predates the device
// authorization API.
cfg := s.cl.GetConfig()
if len(cfg.Servers) == 0 {
http.Error(w, "No Hydra endpoint is configured", http.StatusInternalServerError)
return
}
acceptURL := strings.TrimSuffix(cfg.Servers[0].URL, "/") +
"/admin/oauth2/auth/requests/device/accept?device_challenge=" + url.QueryEscape(challenge)
body, err := json.Marshal(map[string]string{"user_code": userCode})
if err != nil {
http.Error(w, fmt.Sprintf("Failed to encode request body: %s", err), http.StatusInternalServerError)
return
}
req, err := http.NewRequestWithContext(r.Context(), http.MethodPut, acceptURL, bytes.NewReader(body))
if err != nil {
http.Error(w, fmt.Sprintf("Failed to create request: %s", err), http.StatusInternalServerError)
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
hc := cfg.HTTPClient
if hc == nil {
hc = http.DefaultClient
}
res, err := hc.Do(req)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to accept user code request: %s", err), http.StatusInternalServerError)
return
}
defer res.Body.Close() //nolint:errcheck
raw, err := io.ReadAll(io.LimitReader(res.Body, 1<<20))
if err != nil {
http.Error(w, fmt.Sprintf("Failed to read response: %s", err), http.StatusInternalServerError)View on GitHub (pinned to 4174065ffb)
Solutions
- Print/validate cfg.Servers[0].URL before building acceptURL; run it through url.Parse and fail fast with a clear config error.
- Normalize the config value: strings.TrimSpace and reject values that do not start with http:// or https://.
- Since the device_challenge is already url.QueryEscape'd, ensure no double-escaping or manual concatenation of raw query strings; build with url.Values instead.
Example fix
// before
acceptURL := strings.TrimSuffix(cfg.Servers[0].URL, "/") +
"/admin/oauth2/auth/requests/device/accept?device_challenge=" + url.QueryEscape(challenge)
// after
base, err := url.Parse(strings.TrimSpace(cfg.Servers[0].URL))
if err != nil {
http.Error(w, "Invalid server URL in configuration", http.StatusInternalServerError)
return
}
base.Path = strings.TrimSuffix(base.Path, "/") + "/admin/oauth2/auth/requests/device/accept"
q := base.Query(); q.Set("device_challenge", challenge); base.RawQuery = q.Encode()
acceptURL := base.String() Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(cfg.Servers[0].URL)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" {
return fmt.Errorf("invalid server URL in config: %q", cfg.Servers[0].URL)
} Type guard
func isValidHTTPURL(s string) bool {
u, err := url.Parse(strings.TrimSpace(s))
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
} Try / catch
req, err := http.NewRequestWithContext(ctx, http.MethodPut, acceptURL, body)
if err != nil {
log.Printf("bad request URL %q: %v", acceptURL, err)
http.Error(w, "invalid admin URL", http.StatusInternalServerError)
return
} Prevention
- Validate server URLs at config-load time, before any request is built
- Trim whitespace on URL values read from env/config files
- Build query strings with url.Values instead of string concatenation
When it happens
Trigger: url.Parse inside http.NewRequestWithContext fails on acceptURL built as cfg.Servers[0].URL + "/admin/oauth2/auth/requests/device/accept?device_challenge=" + query-escaped challenge. This happens when cfg.Servers[0].URL contains invalid characters, control characters, whitespace, or is empty/garbage (bad config).
Common situations: Misconfigured server URL in the Hydra/ory CLI config (trailing garbage, embedded spaces or newlines from env vars), empty Servers array handled elsewhere but a server entry with a malformed URL, or copy-pasted URLs with invisible 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
- issuer URL must be set unless development mode is enabled
- issuer URL scheme must be HTTPS unless development mode is e
- global secret is not configured
- global secret is too short
- unsupported DSN type
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/aaf905ab4a8bf47f.
Report an issue: GitHub.