kataras/iris · info

empty form

Error message

empty form

What it means

ErrEmptyForm is returned by Context.ReadForm, Context.ReadQuery and Context.ReadBody when the request data being read (form body, URL query, or raw body respectively) is empty, so there is nothing to decode into the target struct. It is a sentinel error that callers can detect with errors.Is.

Source

Thrown at context/context.go:2913

		}

		if m, ok := err.(schema.MultiError); ok {
			if csrfErr, hasCSRFToken := m[CSRFTokenFormKey]; hasCSRFToken {
				_, is := csrfErr.(schema.UnknownKeyError)
				return is

			}
		}

		return false
	}

	// ErrEmptyForm is returned by
	// - `context#ReadForm`
	// - `context#ReadQuery`
	// - `context#ReadBody`
	// when the request data (form, query and body respectfully) is empty.
	ErrEmptyForm = errors.New("empty form")

	// ErrEmptyFormField reports whether a specific field exists but it's empty.
	// Usage: errors.Is(err, ErrEmptyFormField)
	// See postValue method. It's only returned on parsed post value methods.
	ErrEmptyFormField = errors.New("empty form field")

	// ConnectionCloseErrorSubstr if at least one of the given
	// substrings are found in a net.OpError:os.SyscallError error type
	// on `IsErrConnectionReset` then the function will report true.
	ConnectionCloseErrorSubstr = []string{
		"broken pipe",
		"connection reset by peer",
	}

	// IsErrConnectionClosed reports whether the given "err"
	// is caused because of a broken connection.
	IsErrConnectionClosed = func(err error) bool {
		if err == nil {

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Handle the sentinel explicitly with errors.Is(err, iris.ErrEmptyForm) and either bind to zero-value defaults or return 400.
  2. Check that the client actually sends data (query string present, non-empty body, correct Content-Type: application/x-www-form-urlencoded or multipart).
  3. For GET endpoints, prefer ReadQuery and verify the URL includes the expected parameters.
  4. Only require form data when the route semantically needs it; make empty input an allowed case in your handler.

Example fix

// before
var req FilterRequest
if err := ctx.ReadQuery(&req); err != nil {
    ctx.StopWithStatus(400) // fails on empty query string
    return
}
// after
var req FilterRequest
if err := ctx.ReadQuery(&req); err != nil {
    if errors.Is(err, iris.ErrEmptyForm) {
        req = FilterRequest{Page: 1, Limit: 20} // sensible defaults
    } else {
        ctx.StopWithStatus(400)
        return
    }
}
Defensive patterns

Strategy: validation

Validate before calling

var req FilterRequest
if ctx.Request().URL.RawQuery == "" && ctx.Request().ContentLength == 0 {
    req = FilterRequest{Page: 1, Limit: 20} // defaults, skip ReadQuery/ReadForm
} else if err := ctx.ReadQuery(&req); err != nil { /* handle */ }

Try / catch

var req FilterRequest
err := ctx.ReadForm(&req)
if err != nil {
    if errors.Is(err, iris.ErrEmptyForm) {
        // empty payload: use zero-value/defaults, do not fail
    } else {
        ctx.StopWithStatus(iris.StatusBadRequest)
        return
    }
}

Prevention

When it happens

Trigger: Calling ReadQuery when the request URL has no query parameters; calling ReadForm on a request with no form/body payload; calling ReadBody when the request body is empty (e.g. GET with no body, or Content-Length 0).

Common situations: GET requests whose handlers call ReadForm/ReadBody although no payload was sent; clients that send query params on a different HTTP method or URL than expected; HTML forms submitted without any filled fields; wrong Content-Type so the body is not parsed as form data.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/8b3dab65186a7391. Report an issue: GitHub.