gofiber/fiber · error

test: got empty response

Error message

test: got empty response

What it means

Returned by App.Test when reading the synthesized HTTP response hits io.ErrUnexpectedEOF — the in-process server closed the test connection before writing any bytes (app.go:1489-1491). Test() drives the handler through a pipe; if the handler never writes (e.g. calls Ctx.Drop()) the response stream is empty and EOF is translated to this sentinel so callers can distinguish 'no response' from other read failures.

Source

Thrown at app.go:1372

// Hooks returns the hook struct to register hooks.
func (app *App) Hooks() *Hooks {
	return app.hooks
}

// State returns the in-process state struct to store global data between handlers.
// State is process-local and is not shared across prefork workers.
func (app *App) State() *State {
	return app.state
}

// SharedState returns storage-backed shared state.
// SharedState is prefork-safe when Config.SharedStorage is configured.
func (app *App) SharedState() *SharedState {
	return app.sharedState
}

var ErrTestGotEmptyResponse = errors.New("test: got empty response")

// TestConfig is a struct holding Test settings
type TestConfig struct {
	// Timeout defines the maximum duration a
	// test can run before timing out.
	// Default: time.Second
	Timeout time.Duration

	// FailOnTimeout specifies whether the test
	// should return a timeout error if the HTTP response
	// exceeds the Timeout duration.
	// Default: true
	FailOnTimeout bool
}

// Test is used for internal debugging by passing a *http.Request.
// Config is optional and defaults to a 1s error on timeout,
// 0 timeout will disable it completely.

View on GitHub (pinned to a105acad6c)

Solutions

  1. If the empty response is unintended, fix the handler so it always writes a response (c.Send(), c.Status().SendString(), or returning an error that maps to a status) before returning.
  2. If Drop() is intentional, treat ErrTestGotEmptyResponse as the expected outcome and assert it with errors.Is(err, fiber.ErrTestGotEmptyResponse) rather than require.NoError.
  3. Set TestConfig.FailOnTimeout=true (the default) so a hung handler surfaces os.ErrDeadlineExceeded instead of silently producing an empty stream.
  4. Set a non-zero TestConfig.Timeout to bound how long Test() waits before giving up.

Example fix

// before
app.Get("/", func(c fiber.Ctx) error { return c.Drop() })
_, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
require.NoError(t, err) // fails: ErrTestGotEmptyResponse

// after (handler writes a response)
app.Get("/", func(c fiber.Ctx) error { return c.SendString("ok") })
_, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
require.NoError(t, err)
Defensive patterns

Strategy: try-catch

Validate before calling

// Before calling app.Test, ensure the handler always writes a response
// (audit the handler). For Drop()-by-design handlers, expect the sentinel:
func runTest(t *testing.T, app *fiber.App, req *http.Request) {
    _, err := app.Test(req)
    if errors.Is(err, fiber.ErrTestGotEmptyResponse) {
        // handler intentionally drops — treat as expected
        return
    }
    if err != nil { t.Fatal(err) }
}

Try / catch

resp, err := app.Test(req)
switch {
case errors.Is(err, fiber.ErrTestGotEmptyResponse):
    // handler wrote nothing — assert this is intended
case err != nil:
    t.Fatalf("unexpected test error: %v", err)
default:
    // use resp
}

Prevention

When it happens

Trigger: Calling app.Test(req) against a handler that invokes c.Drop() (test at app_test.go:2946-2959), a handler that panics before writing, or a handler path that returns without producing output. Also reachable when FailOnTimeout is false and the handler still produces nothing within the 1s grace window.

Common situations: Unit-testing handlers that intentionally drop the connection; testing error branches that bypass c.Send(); a misconfigured handler chain where middleware short-circuits with Drop(); TestConfig.Timeout=0 with FailOnTimeout=false amplifying the chance of an empty stream.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/2684baa2dc04e098. Report an issue: GitHub.