ory/hydra · error

No Hydra endpoint is configured

Error message

No Hydra endpoint is configured

What it means

POSTdevice accepts the user code with a hand-rolled HTTP request to Hydra's admin device-accept endpoint. It builds the URL from cfg.Servers[0]; when the generated client's config has no servers configured, it responds 500 'No Hydra endpoint is configured' rather than making a request to an invalid URL.

Source

Thrown at cmd/cmd_perform_device_flow.go:194

		return
	}
	userCode, challenge := r.FormValue("user_code"), r.FormValue("device_challenge")
	if userCode == "" {
		http.Error(w, "user_code is required", http.StatusBadRequest)
		return
	}
	if challenge == "" {
		http.Error(w, "device_challenge is required", http.StatusBadRequest)
		return
	}

	// 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

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Set the Hydra admin URL on the client config before starting the device flow (e.g. cfg.SetServerURL(...)) or set the corresponding environment variable
  2. Verify the environment variable used to configure the client is exported and non-empty in the shell running the command
  3. Check how the client is constructed in the CLI entrypoint and ensure the config is passed through to deviceSrv
  4. Run with debug logging to confirm the resolved configuration

Example fix

// before
cl := hydra.NewAPIClient(hydra.NewConfiguration())
// after
cfg := hydra.NewConfiguration()
cfg.Servers = hydra.ServerConfigurations{{URL: "http://127.0.0.1:4445"}}
cl := hydra.NewAPIClient(cfg)
Defensive patterns

Strategy: validation

Validate before calling

cfg := s.cl.GetConfig()
if len(cfg.Servers) == 0 || cfg.Servers[0].URL == "" {
	return errors.New("hydra admin URL not configured")
}

Type guard

func hasServerURL(cfg *hydra.Configuration) bool {
	return cfg != nil && len(cfg.Servers) > 0 && cfg.Servers[0].URL != ""
}

Try / catch

if err != nil {
	log.Printf("device accept request failed: %v", err)
	http.Error(w, "failed to accept user code", http.StatusBadGateway)
	return
}

Prevention

When it happens

Trigger: The hydra client configuration was created without setting any server URL (cfg.Servers empty) before POSTdevice runs.

Common situations: HYDRA_ADMIN_URL (or equivalent config) not set; client constructed with the default configuration and SetServerURL/SetServers never called; environment variable misspelled or empty in the CLI invocation; config loading silently skipped in tests.

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/d36559e11c3b2b8b. Report an issue: GitHub.