juanfont/headscale · error
%s confirm form: unterminated input tag
Error message
%s confirm form: unterminated input tag
What it means
After locating the `<input` tag for the CSRF field, the parser could not find a closing `>` in the remainder of the document (`strings.Index(htmlBody[tagStart:], ">")` returned -1). The tag is never terminated, so its attributes cannot be sliced out safely.
Source
Thrown at integration/scenario.go:1282
}
formAction := htmlBody[actionStart : actionStart+actionEnd]
// Extract hidden CSRF input value. The rendered <input> has
// attributes in name-type-value order so we grab the whole tag.
before, _, ok := strings.Cut(htmlBody, `name="headscale_register_confirm"`)
if !ok {
return "", nil, fmt.Errorf("%s confirm form: no CSRF input", hostname) //nolint:err113
}
tagStart := strings.LastIndex(before, "<input")
if tagStart == -1 {
return "", nil, fmt.Errorf("%s confirm form: no input tag for CSRF", hostname) //nolint:err113
}
tagEnd := strings.Index(htmlBody[tagStart:], ">")
if tagEnd == -1 {
return "", nil, fmt.Errorf("%s confirm form: unterminated input tag", hostname) //nolint:err113
}
inputTag := htmlBody[tagStart : tagStart+tagEnd+1]
valIdx := strings.Index(inputTag, `value="`)
if valIdx == -1 {
return "", nil, fmt.Errorf("%s confirm form: no value in CSRF input", hostname) //nolint:err113
}
valStart := valIdx + len(`value="`)
valEnd := strings.Index(inputTag[valStart:], `"`)
csrfToken := inputTag[valStart : valStart+valEnd]
// Build the absolute POST URL from the response's request URL.
base := prevResp.Request.URL
confirmURL := &url.URL{
Scheme: base.Scheme,
Host: base.Host,View on GitHub (pinned to 565fd254d0)
Solutions
- Dump `htmlBody` length and tail when the error fires to confirm truncation.
- Retry the GET of the confirm page; transient truncation in containerized tests is usually network flake.
- If reproducible, fix the template that renders the unterminated input tag.
Defensive patterns
Strategy: retry
Prevention
- Check Content-Length vs actual bytes read to detect truncated bodies early.
- Retry the GET once on truncation — usually a flaky container network.
- Fix malformed templates at the source rather than loosening the parser.
When it happens
Trigger: The document ends (or is truncated) between `<input` and its closing angle bracket — truncated response body, connection cut mid-body, or a template that emits a malformed input tag.
Common situations: Proxy or test harness truncates the HTML body; template file corrupted or partially written; the page is streamed and read before completion.
Related errors
- %s confirm form: no CSRF input
- %s confirm form: no input tag for CSRF
- %s confirm form: no value in CSRF input
- tag should be lowercase
- %s confirm form: unterminated action attribute
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/f8dcef6afc26d10c.
Report an issue: GitHub.