Skip to content

🐛 [Bug]: Fiber v3 OTel middleware can stall browser request/response flow when tracing static assets with default config #1734

@edgarsilva

Description

@edgarsilva

Bug Description

Summary

When using github.com/gofiber/contrib/v3/otel middleware with default config, enabling request tracing for static assets (/public/*, /favicon.ico) can cause request flow to never complete, appear stalled/hung in browser-driven pages (signin page + static assets), seems to be panic b/c of nil pointer, but since we have the recover middleware it just hangs.

In our case, disabling the middleware immediately restores normal behavior.

This happens both with:

  1. plain tracer (otel.Tracer(...) / default provider path), and
  2. stdout exporter (stdouttrace.WithPrettyPrint()).

Workaround is to skip static paths via WithNext(...).

Environment

  • Go: 1.25+
  • Fiber: github.com/gofiber/fiber/v3 v3.1.0
  • Fiber static middleware package: github.com/gofiber/fiber/v3/middleware/static (same Fiber module/version: v3.1.0)
  • Middleware: github.com/gofiber/contrib/v3/otel v1.1.0
  • OTel: go.opentelemetry.io/otel v1.40.0
  • OS: Linux (reproduced locally)

What we observe

  • App boots, routes register, and spans are emitted.
  • Browser signin flow hangs / does not complete reliably when middleware is enabled.
  • If middleware is disabled, flow works normally.
  • If middleware is enabled and we remove Recover middlewar nil pointer panic.
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x739393]

goroutine 18 [running]:
github.com/valyala/fasthttp.(*fsFile).decReadersCount(0x0)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/fs.go:630 +0x13
github.com/valyala/fasthttp.(*fsSmallFileReader).Close(0x1ef1b832708)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/fs.go:708 +0x25
github.com/gofiber/contrib/v3/otel.(*bodyStreamSizeReader).Close(0xec5660?)
	/home/edgar/go/pkg/mod/github.com/gofiber/contrib/v3/otel@v1.1.0/fiber.go:80 +0x3c
github.com/valyala/fasthttp.(*Response).closeBodyStream(0x1ef1b724008, {0x0, 0x0})
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/http.go:2144 +0xb7
github.com/valyala/fasthttp.(*Response).ResetBody(0x1ef1b724008)

Also just happened with .well-known.devtools returning a 404 ->

12:05:00 | 404 |    1.893265ms |       127.0.0.1 | GET     | /.well-known/appspecific/com.chrome.devtools.json  | Not Found
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0xcb9193]
goroutine 181 [running]:
github.com/valyala/fasthttp.(*fsFile).decReadersCount(0x0)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/fs.go:630 +0x13
github.com/valyala/fasthttp.(*fsSmallFileReader).Close(0x3f5274fa7308)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/fs.go:708 +0x25
github.com/gofiber/contrib/v3/otel.(*bodyStreamSizeReader).Close(0x1e681a0?)
	/home/edgar/go/pkg/mod/github.com/gofiber/contrib/v3/otel@v1.1.0/fiber.go:80 +0x3c
github.com/valyala/fasthttp.(*Response).closeBodyStream(0x3f5274e2c008, {0x0, 0x0})
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/http.go:2144 +0xb7
github.com/valyala/fasthttp.(*Response).ResetBody(0x3f5274e2c008)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/http.go:697 +0x45
github.com/valyala/fasthttp.(*Response).resetSkipHeader(...)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/http.go:1189
github.com/valyala/fasthttp.(*Response).Reset(0x3f5274e2c008)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/http.go:1179 +0x3c
github.com/valyala/fasthttp.(*RequestCtx).reset(0x3f5274e2c008)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/server.go:867 +0x2f
github.com/valyala/fasthttp.(*Server).releaseCtx(0x3f52740b8fc8, 0x3f5274e2c008)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/server.go:2914 +0x2a
github.com/valyala/fasthttp.(*Server).serveConn(0x3f52740b8fc8, {0x148bf98, 0x3f527438e188})
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/server.go:2591 +0x1cb4
github.com/valyala/fasthttp.(*workerPool).workerFunc(0x3f52740f4900, 0x3f5274268740)
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/workerpool.go:225 +0x92
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/workerpool.go:197 +0x32
created by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 107
	/home/edgar/go/pkg/mod/github.com/valyala/fasthttp@v1.69.0/workerpool.go:196 +0x185
Process Exit with Code: 2 

Workaround
Skip static paths in middleware:

app.Use(otel.Middleware(
    otel.WithNext(func(c fiber.Ctx) bool {
        path := c.Path()
        return strings.HasPrefix(path, "/public/") ||
				strings.HasPrefix(path, "/.well-known/") ||
				path == "/favicon.ico"
    }),
))

This removes the stall/hang behavior in our setup.

Additional Notes

  • WithoutMetrics(true) did not materially change the behavior in our case.
  • We still saw request spans when enabled, so middleware was active and tracing.
  • This may be related to how static middleware /body-stream requests are handled under default middleware behavior for Fiber v3.

How to Reproduce

Steps to reproduce the behavior:

  1. Add middleware with default config:
    app.Use(otel.Middleware())
  2. Serve static files and load a page that pulls several static assets (e.g. /public/load.js + /public/global.css + images/favicon).
  3. Observe:
    • traces are generated
    • routes are registered and app starts
    • browser request flow intermittently hangs / never fully completes
  4. Disable middleware:
    • app behaves normally again.

Expected Behavior

  • Enabling github.com/gofiber/contrib/v3/otel middleware should not alter normal request/response flow.
  • Browser requests (including pages that load static assets) should complete normally and consistently.
  • Static middleware (github.com/gofiber/fiber/v3/middleware/static) should continue serving assets without hangs/timeouts.
  • OTel middleware should only add tracing/metrics instrumentation; it should not panic, block, stall, or delay response completion.

Contrib package Version

github.com/gofiber/contrib/v3/otel v1.1.0

Code Snippet (optional)

package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"

	otelfiber "github.com/gofiber/contrib/v3/otel"
	"github.com/gofiber/fiber/v3"
	"github.com/gofiber/fiber/v3/middleware/static"
)

func main() {
	port := flag.Int("port", 3005, "server port")
	flag.Parse()

	publicDir, cleanup, err := seedPublicFiles()
	if err != nil {
		log.Fatal(err)
	}
	defer cleanup()

	app := fiber.New()
	app.Use(otelfiber.Middleware())
	app.Use("/public", static.New(publicDir))

	app.Get("/", func(c fiber.Ctx) error {
		return c.Type("html").SendString(`<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="/public/repro.css" />
  </head>
  <body>
    <h1>OTel Fiber Repro</h1>
    <img src="/public/repro.png" alt="pixel" />
  </body>
</html>`)
	})

	addr := fmt.Sprintf(":%d", *port)
	log.Printf("open http://localhost:%d/", *port)
	log.Fatal(app.Listen(addr))
}

func seedPublicFiles() (string, func(), error) {
	dir, err := os.MkdirTemp("", "otel-repro-public-")
	if err != nil {
		return "", nil, err
	}

	if err := os.WriteFile(filepath.Clean(filepath.Join(dir, "repro.css")), []byte("body{font-family:sans-serif;}"), 0o644); err != nil {
		_ = os.RemoveAll(dir)
		return "", nil, err
	}

	if err := os.WriteFile(filepath.Clean(filepath.Join(dir, "repro.png")), []byte("x"), 0o644); err != nil {
		_ = os.RemoveAll(dir)
		return "", nil, err
	}

	cleanup := func() {
		_ = os.RemoveAll(dir)
	}

	return dir, cleanup, nil
}

Checklist:

  • I agree to follow Fiber's Code of Conduct.
  • I have checked for existing issues that describe my problem prior to opening this one.
  • I understand that improperly formatted bug reports may be closed without explanation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ☢️ BugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions