air-verse/air · warning
proxy handler: unable to create request
Error message
proxy handler: unable to create request
What it means
After parsing the form, proxyHandler builds a new outbound http.NewRequest to forward the request to the app on AppPort. If constructing that request fails (invalid method, unparseable URL, unsupported body type), the proxy replies with HTTP 500 and this message.
Source
Thrown at runner/proxy.go:168
func (p *Proxy) proxyHandler(w http.ResponseWriter, r *http.Request) {
appURL := r.URL
appURL.Scheme = "http"
appURL.Host = fmt.Sprintf("localhost:%d", p.config.AppPort)
if err := r.ParseForm(); err != nil {
http.Error(w, "proxy handler: bad form", http.StatusInternalServerError)
return
}
var body io.Reader
if len(r.Form) > 0 {
body = strings.NewReader(r.Form.Encode())
} else {
body = r.Body
}
req, err := http.NewRequest(r.Method, appURL.String(), body)
if err != nil {
http.Error(w, "proxy handler: unable to create request", http.StatusInternalServerError)
return
}
// Copy the headers from the original request
for name, values := range r.Header {
for _, value := range values {
req.Header.Add(name, value)
}
}
delHopByHopHeaders(req.Header)
req.Header.Set("X-Forwarded-For", r.RemoteAddr)
// set the via header
viaHeaderValue := fmt.Sprintf("%s %s", r.Proto, r.Host)
req.Header.Set("Via", viaHeaderValue)
// air will restart the server. it may take a few seconds for it to start back up.
// therefore, we retry until the server becomes available or this retry loop exits with an error.View on GitHub (pinned to 71ea1dee05)
Solutions
- Verify `app_port` in .air.toml is a plain valid TCP port (1-65535)
- Check what method the client is sending — use a standard HTTP verb (GET/POST/...)
- Enable air's proxy debug logs and inspect the incoming request line
- Reproduce with curl using a standard method to confirm the proxy itself is healthy
Example fix
// before (.air.toml) app_port = "http://localhost:3000" // invalid // after app_port = 3000
Defensive patterns
Strategy: validation
Validate before calling
// ensure app_port yields a valid URL
u := "http://localhost:" + strconv.Itoa(appPort)
if _, err := url.Parse(u); err != nil {
return fmt.Errorf("invalid app_port %d: %w", appPort, err)
} Try / catch
resp, err := client.Do(req)
if err != nil && resp != nil && resp.StatusCode == 500 {
b, _ := io.ReadAll(resp.Body)
if strings.Contains(string(b), "unable to create request") {
// check HTTP verb and app_port config
}
} Prevention
- Keep app_port a plain integer port (1-65535) in .air.toml
- Use standard HTTP methods only in clients targeting the proxy
- Validate proxy requests with curl before debugging exotic clients
- Re-check app_port after renaming services/ports
When it happens
Trigger: proxyHandler calls http.NewRequest(r.Method, appURL.String(), body) and it errors — typically an invalid HTTP method token from the client or an appURL that fails url.Parse (app_port config producing an invalid host string).
Common situations: Clients sending requests with malformed/custom method tokens; app_port set to a value that produces an invalid URL (e.g. out-of-range port with weird formatting); exotic body types breaking NewRequest's io.Reader handling.
Related errors
- proxy inject: failed to init gzip reader: %w
- proxy inject: failed to read body from http response: %w
- proxy handler: bad form
AI-assisted analysis of air-verse/air@71ea1dee05 (2026-08-31).
Data as JSON: /api/errors/c7acf1fbdbfc48ba.
Report an issue: GitHub.