<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Fiber Blog</title>
        <link>https://docs.gofiber.io/blog</link>
        <description>Fiber Blog</description>
        <lastBuildDate>Mon, 11 May 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[The Fiber CLI]]></title>
            <link>https://docs.gofiber.io/blog/fiber-cli</link>
            <guid>https://docs.gofiber.io/blog/fiber-cli</guid>
            <pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Live reload, project scaffolding, static file server, version migration  -  the Fiber CLI handles the tasks around your code so you can focus on the code itself.]]></description>
            <content:encoded><![CDATA[<p>Most Go web frameworks give you a library and send you on your way. Fiber ships a CLI tool that handles the repetitive tasks around development: live reload when files change, project scaffolding from templates, serving static files with one command, and migrating between Fiber versions automatically.</p>
<p>You do not need the CLI to use Fiber. But once you try <code>fiber dev</code> instead of manually restarting your server after every change, you will not go back.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="installation">Installation<a href="https://docs.gofiber.io/blog/fiber-cli#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation" translate="no">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">go install github.com/gofiber/cli/fiber@latest</span><br></div></code></pre></div></div>
<p>Requires a recent Go version. After installation, <code>fiber</code> is available in your terminal.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fiber-dev-----live-reload">fiber dev  -  Live Reload<a href="https://docs.gofiber.io/blog/fiber-cli#fiber-dev-----live-reload" class="hash-link" aria-label="Direct link to fiber dev  -  Live Reload" title="Direct link to fiber dev  -  Live Reload" translate="no">​</a></h2>
<p>The most-used command. It watches your project files and restarts the server whenever something changes:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">fiber dev</span><br></div></code></pre></div></div>
<p>That is it. Edit a <code>.go</code> file, save, and your server restarts automatically. No external tools like Air or nodemon needed.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="customizing-the-watch">Customizing the Watch<a href="https://docs.gofiber.io/blog/fiber-cli#customizing-the-watch" class="hash-link" aria-label="Direct link to Customizing the Watch" title="Direct link to Customizing the Watch" translate="no">​</a></h3>
<p>By default, <code>fiber dev</code> watches <code>.go</code>, <code>.tmpl</code>, <code>.tpl</code>, and <code>.html</code> files. You can adjust this:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Watch additional file types</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber dev -e go,tmpl,html,css,js</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Ignore specific directories</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber dev -D assets,tmp,vendor,node_modules,dist</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Set a delay before restarting (avoid rapid restarts during save-all)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber dev -d 2s</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Run commands before each restart</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber dev --pre-run="go generate ./..."</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Pass arguments to your app</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber dev -a "-port=8080,-debug=true"</span><br></div></code></pre></div></div>
<p>The <code>--pre-run</code> flag is powerful. If your project uses code generation, template compilation, or asset building, those commands run automatically before each restart.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="watch-a-specific-target">Watch a Specific Target<a href="https://docs.gofiber.io/blog/fiber-cli#watch-a-specific-target" class="hash-link" aria-label="Direct link to Watch a Specific Target" title="Direct link to Watch a Specific Target" translate="no">​</a></h3>
<p>If your <code>main.go</code> is not in the project root:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">fiber dev -t ./cmd/server</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fiber-new-----project-scaffolding">fiber new  -  Project Scaffolding<a href="https://docs.gofiber.io/blog/fiber-cli#fiber-new-----project-scaffolding" class="hash-link" aria-label="Direct link to fiber new  -  Project Scaffolding" title="Direct link to fiber new  -  Project Scaffolding" translate="no">​</a></h2>
<p>Generate a new Fiber project from templates:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Basic project structure</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber new myapp</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># With a custom Go module name</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber new myapp github.com/yourname/myapp</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Complex project structure with more boilerplate</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber new myapp -t complex</span><br></div></code></pre></div></div>
<p>The <strong>basic</strong> template gives you a minimal Fiber project: <code>main.go</code>, <code>go.mod</code>, and a simple route. The <strong>complex</strong> template includes directory structure, configuration, middleware setup, and more.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="custom-templates">Custom Templates<a href="https://docs.gofiber.io/blog/fiber-cli#custom-templates" class="hash-link" aria-label="Direct link to Custom Templates" title="Direct link to Custom Templates" translate="no">​</a></h3>
<p>You can generate projects from any GitHub repository:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># From a specific GitHub repo</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber new myapp -t complex -r your-org/your-template</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># From any Git URL</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber new myapp -t complex -r https://gitlab.com/team/fiber-template.git</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># SSH-based repo</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber new myapp -t complex -r git@github.com:team/template.git</span><br></div></code></pre></div></div>
<p>This lets your team maintain a standard project template and generate new services from it in seconds.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fiber-serve-----static-file-server">fiber serve  -  Static File Server<a href="https://docs.gofiber.io/blog/fiber-cli#fiber-serve-----static-file-server" class="hash-link" aria-label="Direct link to fiber serve  -  Static File Server" title="Direct link to fiber serve  -  Static File Server" translate="no">​</a></h2>
<p>Need to serve static files quickly? Maybe you are developing a frontend, reviewing a build output, or hosting documentation:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Serve the current directory on :3000</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber serve</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Serve a specific directory on a custom port</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber serve --dir ./dist --addr :8080</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Enable directory browsing</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber serve --browse</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Enable compression and CORS</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber serve --compress --cors</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Serve with TLS</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber serve --cert ./cert.pem --key ./key.pem</span><br></div></code></pre></div></div>
<p>This is a full-featured static file server with caching, compression, CORS, health checks, byte-range requests, and optional TLS  -  all without writing a single line of Go code.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="all-serve-options">All serve options<a href="https://docs.gofiber.io/blog/fiber-cli#all-serve-options" class="hash-link" aria-label="Direct link to All serve options" title="Direct link to All serve options" translate="no">​</a></h3>
<table><thead><tr><th>Flag</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>--addr</code></td><td><code>:3000</code></td><td>Listen address</td></tr><tr><td><code>--dir</code></td><td><code>.</code></td><td>Directory to serve</td></tr><tr><td><code>--browse</code></td><td><code>false</code></td><td>Enable directory listing</td></tr><tr><td><code>--compress</code></td><td><code>false</code></td><td>Enable gzip/brotli compression</td></tr><tr><td><code>--cors</code></td><td><code>false</code></td><td>Enable CORS headers</td></tr><tr><td><code>--cache</code></td><td><code>10s</code></td><td>Cache duration</td></tr><tr><td><code>--index</code></td><td><code>index.html</code></td><td>Index file names</td></tr><tr><td><code>--cert</code> / <code>--key</code></td><td>-</td><td>TLS certificate and key</td></tr><tr><td><code>--prefork</code></td><td><code>false</code></td><td>Enable prefork mode</td></tr><tr><td><code>--download</code></td><td><code>false</code></td><td>Force file downloads</td></tr><tr><td><code>--range</code></td><td><code>false</code></td><td>Enable byte-range requests</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fiber-migrate-----version-migration">fiber migrate  -  Version Migration<a href="https://docs.gofiber.io/blog/fiber-cli#fiber-migrate-----version-migration" class="hash-link" aria-label="Direct link to fiber migrate  -  Version Migration" title="Direct link to fiber migrate  -  Version Migration" translate="no">​</a></h2>
<p>Upgrading Fiber versions usually means finding breaking changes, updating import paths, and adjusting API calls. The CLI automates this:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Migrate to Fiber v3</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber migrate --to 3.0.0</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Also refresh third-party modules (contrib, storage, template)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber migrate --to 3.0.0 --third-party contrib,storage,template</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Verbose output for debugging</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber migrate --to 3.0.0 --verbose</span><br></div></code></pre></div></div>
<p>The migration tool updates your <code>go.mod</code>, adjusts import paths, and runs <code>go mod tidy</code> automatically. It covers the mechanical work of migration so you can focus on the API changes that need manual attention.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fiber-upgrade-----self-update">fiber upgrade  -  Self-Update<a href="https://docs.gofiber.io/blog/fiber-cli#fiber-upgrade-----self-update" class="hash-link" aria-label="Direct link to fiber upgrade  -  Self-Update" title="Direct link to fiber upgrade  -  Self-Update" translate="no">​</a></h2>
<p>Keep the CLI itself up to date:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">fiber upgrade</span><br></div></code></pre></div></div>
<p>Checks for the latest release and updates in place.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fiber-version">fiber version<a href="https://docs.gofiber.io/blog/fiber-cli#fiber-version" class="hash-link" aria-label="Direct link to fiber version" title="Direct link to fiber version" translate="no">​</a></h2>
<p>Check your CLI and Fiber versions:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">fiber version</span><br></div></code></pre></div></div>
<p>Shows both the CLI version and the latest available version, so you know when an update is available.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-development-workflow">The Development Workflow<a href="https://docs.gofiber.io/blog/fiber-cli#the-development-workflow" class="hash-link" aria-label="Direct link to The Development Workflow" title="Direct link to The Development Workflow" translate="no">​</a></h2>
<p>A typical development session with the Fiber CLI:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Scaffold a new project</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber new my-api github.com/myorg/my-api</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cd my-api</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Start developing with live reload</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber dev</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># In another terminal, serve the frontend</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">fiber serve --dir ./frontend/dist --addr :8080 --cors</span><br></div></code></pre></div></div>
<p>The CLI handles the infrastructure. You write the code.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-cli#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://github.com/gofiber/cli" target="_blank" rel="noopener noreferrer" class="">Fiber CLI Repository</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/recipes/">Recipes  -  for more project examples</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New in v3</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>cli</category>
            <category>tooling</category>
            <category>development</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[The Recipes Cookbook]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-recipes</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-recipes</guid>
            <pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[70+ ready-to-run examples covering auth, databases, deployment, Docker, and more  -  the fastest way to learn Fiber by doing.]]></description>
            <content:encoded><![CDATA[<p>Documentation tells you what an API does. Blog posts explain the why. But when you need to build something real  -  authentication with JWT, deployment to AWS, a WebSocket chat, a CRUD app with Postgres  -  what you really want is working code you can copy and adapt.</p>
<p>That is what the Fiber Recipes repository is. Over 70 complete, runnable example projects covering everything from "Hello World" to clean architecture with Docker, OAuth2, and Kubernetes. Every recipe is a self-contained Go project with its own <code>go.mod</code>, <code>main.go</code>, and README.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-find-them">Where to Find Them<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#where-to-find-them" class="hash-link" aria-label="Direct link to Where to Find Them" title="Direct link to Where to Find Them" translate="no">​</a></h2>
<p>The recipes live in two places:</p>
<ul>
<li class=""><strong>Browse online</strong>: <a href="https://docs.gofiber.io/recipes/" target="_blank" rel="noopener noreferrer" class="">docs.gofiber.io/recipes</a>  -  searchable, categorized, with full READMEs</li>
<li class=""><strong>Clone and run</strong>: <a href="https://github.com/gofiber/recipes" target="_blank" rel="noopener noreferrer" class="">github.com/gofiber/recipes</a>  -  <code>git clone</code>, <code>cd</code> into a recipe, <code>go run .</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="recipes-by-category">Recipes by Category<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#recipes-by-category" class="hash-link" aria-label="Direct link to Recipes by Category" title="Direct link to Recipes by Category" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="authentication">Authentication<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#authentication" class="hash-link" aria-label="Direct link to Authentication" title="Direct link to Authentication" translate="no">​</a></h3>
<table><thead><tr><th>Recipe</th><th>What It Shows</th></tr></thead><tbody><tr><td><a class="" href="https://docs.gofiber.io/recipes/auth-jwt">auth-jwt</a></td><td>Simple JWT authentication</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/auth-docker-postgres-jwt">auth-docker-postgres-jwt</a></td><td>JWT + Docker + Postgres  -  full stack</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/firebase-auth">firebase-auth</a></td><td>Firebase authentication integration</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/oauth2">oauth2</a></td><td>GitHub OAuth2 flow</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/oauth2-google">oauth2-google</a></td><td>Google OAuth2 flow</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/todo-app-with-auth-gorm">todo-app-with-auth-gorm</a></td><td>Todo app with auth and GORM</td></tr></tbody></table>
<p>If you need authentication in your Fiber app, start with <code>auth-jwt</code> for the simplest case or <code>auth-docker-postgres-jwt</code> for a production-like setup.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="databases">Databases<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#databases" class="hash-link" aria-label="Direct link to Databases" title="Direct link to Databases" translate="no">​</a></h3>
<table><thead><tr><th>Recipe</th><th>What It Shows</th></tr></thead><tbody><tr><td><a class="" href="https://docs.gofiber.io/recipes/gorm">gorm</a></td><td>GORM with SQLite</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/gorm-postgres">gorm-postgres</a></td><td>GORM with PostgreSQL</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/gorm-mysql">gorm-mysql</a></td><td>GORM with MySQL</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/mongodb">mongodb</a></td><td>MongoDB driver</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/ent-mysql">ent-mysql</a></td><td>Ent ORM with MySQL</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/sqlc">sqlc</a></td><td>Type-safe SQL with sqlc</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/sqlboiler">sqlboiler</a></td><td>SQLBoiler ORM</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/postgresql">postgresql</a></td><td>Raw PostgreSQL driver</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/mysql">mysql</a></td><td>Raw MySQL driver</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/neo4j">neo4j</a></td><td>Neo4j graph database</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/memgraph">memgraph</a></td><td>Memgraph graph database</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deployment">Deployment<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#deployment" class="hash-link" aria-label="Direct link to Deployment" title="Direct link to Deployment" translate="no">​</a></h3>
<table><thead><tr><th>Recipe</th><th>What It Shows</th></tr></thead><tbody><tr><td><a class="" href="https://docs.gofiber.io/recipes/docker-nginx-loadbalancer">docker-nginx-loadbalancer</a></td><td>Docker + Nginx load balancing</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/docker-mariadb-clean-arch">docker-mariadb-clean-arch</a></td><td>Dockerized MariaDB with Clean Architecture</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/k8s">k8s</a></td><td>Kubernetes deployment</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/aws-eb">aws-eb</a></td><td>AWS Elastic Beanstalk</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/aws-sam-container">aws-sam-container</a></td><td>AWS SAM containerized</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/cloud-run">cloud-run</a></td><td>Google Cloud Run</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/heroku">heroku</a></td><td>Heroku deployment</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/vercel">vercel</a></td><td>Vercel deployment</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/seenode">seenode</a></td><td>Seenode cloud platform</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/cloudflare-workers">cloudflare-workers</a></td><td>Cloudflare Container Workers</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="real-time">Real-Time<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#real-time" class="hash-link" aria-label="Direct link to Real-Time" title="Direct link to Real-Time" translate="no">​</a></h3>
<table><thead><tr><th>Recipe</th><th>What It Shows</th></tr></thead><tbody><tr><td><a class="" href="https://docs.gofiber.io/recipes/websocket">websocket</a></td><td>Basic WebSocket communication</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/websocket-chat">websocket-chat</a></td><td>Real-time chat app</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/socketio">socketio</a></td><td>Socket.io chatroom</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/sse">sse</a></td><td>Server-Sent Events</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="architecture-patterns">Architecture Patterns<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#architecture-patterns" class="hash-link" aria-label="Direct link to Architecture Patterns" title="Direct link to Architecture Patterns" translate="no">​</a></h3>
<table><thead><tr><th>Recipe</th><th>What It Shows</th></tr></thead><tbody><tr><td><a class="" href="https://docs.gofiber.io/recipes/clean-architecture">clean-architecture</a></td><td>Clean Architecture in Go</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/clean-code">clean-code</a></td><td>Clean Code patterns</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/hexagonal">hexagonal</a></td><td>Hexagonal Architecture with MongoDB</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="security">Security<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#security" class="hash-link" aria-label="Direct link to Security" title="Direct link to Security" translate="no">​</a></h3>
<table><thead><tr><th>Recipe</th><th>What It Shows</th></tr></thead><tbody><tr><td><a class="" href="https://docs.gofiber.io/recipes/csrf">csrf</a></td><td>CSRF protection</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/csrf-with-session">csrf-with-session</a></td><td>CSRF + session management</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/https-tls">https-tls</a></td><td>HTTPS with TLS</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/https-pkcs12-tls">https-pkcs12-tls</a></td><td>HTTPS with PKCS12 certificates</td></tr><tr><td><a class="" href="https://docs.gofiber.io/recipes/autocert">autocert</a></td><td>Automatic TLS certificate management</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-use-a-recipe">How to Use a Recipe<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#how-to-use-a-recipe" class="hash-link" aria-label="Direct link to How to Use a Recipe" title="Direct link to How to Use a Recipe" translate="no">​</a></h2>
<p>Every recipe follows the same pattern:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Clone the recipes repository</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">git clone https://github.com/gofiber/recipes.git</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cd recipes</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Pick a recipe</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cd auth-jwt</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Read the README</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cat README.md</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># Run it</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">go run .</span><br></div></code></pre></div></div>
<p>Most recipes start a server on <code>:3000</code>. Some require Docker for databases  -  the README tells you what you need.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="building-on-recipes">Building on Recipes<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#building-on-recipes" class="hash-link" aria-label="Direct link to Building on Recipes" title="Direct link to Building on Recipes" translate="no">​</a></h2>
<p>Recipes are starting points, not finished applications. The typical workflow:</p>
<ol>
<li class="">Find a recipe that matches your use case</li>
<li class="">Copy it into your project (or use it as reference)</li>
<li class="">Adapt the code to your needs</li>
<li class="">Add production concerns (error handling, logging, config)</li>
</ol>
<p>The <code>clean-architecture</code> and <code>hexagonal</code> recipes are especially useful as project templates  -  they show how to structure a larger Fiber application with layers, interfaces, and dependency injection.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="contributing-recipes">Contributing Recipes<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#contributing-recipes" class="hash-link" aria-label="Direct link to Contributing Recipes" title="Direct link to Contributing Recipes" translate="no">​</a></h2>
<p>If you have built something interesting with Fiber, the community would benefit from seeing it. The recipes repository accepts contributions following the existing pattern: one directory per recipe, a <code>go.mod</code>, a <code>main.go</code>, and a <code>README.md</code> that explains what the recipe demonstrates.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-recipes#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/recipes/">Recipes Documentation</a></li>
<li class=""><a href="https://github.com/gofiber/recipes" target="_blank" rel="noopener noreferrer" class="">Recipes Repository</a></li>
<li class=""><a href="https://github.com/gofiber/awesome-fiber" target="_blank" rel="noopener noreferrer" class="">Awesome Fiber</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>recipes</category>
            <category>examples</category>
            <category>cookbook</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Contrib Packages]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-contrib-packages</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-contrib-packages</guid>
            <pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[JWT auth, WebSockets, OpenTelemetry, Swagger docs, Circuit Breaker  -  the official contrib middleware that ships separately so your core stays lean.]]></description>
            <content:encoded><![CDATA[<p>Fiber's core ships with 20+ middleware  -  logger, CORS, rate limiter, sessions, and more. But some middleware needs external dependencies: JWT requires a token library, OpenTelemetry needs the OTel SDK, WebSockets depend on a WebSocket implementation. Instead of bloating Fiber's core with these dependencies, they live in a separate repository: <a href="https://github.com/gofiber/contrib" target="_blank" rel="noopener noreferrer" class="">gofiber/contrib</a>.</p>
<p>The contrib packages are first-party middleware. Same team, same quality, same release cycle. The only difference is that they have external Go dependencies, so they are imported separately to keep your <code>go.sum</code> clean when you do not need them.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-in-contrib">What is in Contrib<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#what-is-in-contrib" class="hash-link" aria-label="Direct link to What is in Contrib" title="Direct link to What is in Contrib" translate="no">​</a></h2>
<p>The contrib repository contains 18+ middleware packages. Here are the ones you will reach for most often:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="jwt-authentication">JWT Authentication<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#jwt-authentication" class="hash-link" aria-label="Direct link to JWT Authentication" title="Direct link to JWT Authentication" translate="no">​</a></h3>
<p>The most popular contrib package. It validates JSON Web Tokens and protects routes:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> jwtware </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/jwt"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">jwtware</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">jwtware</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    SigningKey</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> jwtware</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SigningKey</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">Key</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token function" style="color:#d73a49">byte</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"your-secret-key"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/protected"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    user </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Locals</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"user"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">jwt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Token</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    claims </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Claims</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">jwt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MapClaims</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"user"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> claims</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"sub"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The middleware extracts the token from the <code>Authorization: Bearer &lt;token&gt;</code> header, validates it, and stores the parsed token in <code>c.Locals("user")</code>. Invalid or missing tokens return 401 automatically.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="websocket">WebSocket<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#websocket" class="hash-link" aria-label="Direct link to WebSocket" title="Direct link to WebSocket" translate="no">​</a></h3>
<p>Real-time communication with WebSocket support:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/websocket"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/ws"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> websocket</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">websocket</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Conn</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        mt</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> msg</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ReadMessage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">break</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Echo the message back</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteMessage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mt</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> msg</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The WebSocket middleware upgrades HTTP connections to WebSocket and gives you a connection object with <code>ReadMessage</code> / <code>WriteMessage</code> for bidirectional communication.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="opentelemetry-otelfiber">OpenTelemetry (otelfiber)<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#opentelemetry-otelfiber" class="hash-link" aria-label="Direct link to OpenTelemetry (otelfiber)" title="Direct link to OpenTelemetry (otelfiber)" translate="no">​</a></h3>
<p>Distributed tracing and metrics for your Fiber app:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/otelfiber/v2"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">otelfiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Middleware</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>One line. Every request gets a trace span with method, route, status code, and duration. The spans flow into whatever OpenTelemetry collector you have configured  -  Jaeger, Zipkin, Datadog, Grafana Tempo.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="swagger">Swagger<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#swagger" class="hash-link" aria-label="Direct link to Swagger" title="Direct link to Swagger" translate="no">​</a></h3>
<p>Auto-serve your Swagger/OpenAPI documentation:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/swagger"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">swagger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">swagger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    BasePath</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/api/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    FilePath</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./docs/swagger.json"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Path</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"docs"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This serves the Swagger UI at <code>/docs</code> with your API specification. Generate the spec with tools like <code>swag</code> or write it manually.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="socketio">Socket.io<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#socketio" class="hash-link" aria-label="Direct link to Socket.io" title="Direct link to Socket.io" translate="no">​</a></h3>
<p>Full Socket.io server implementation for real-time event-based communication:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/socketio"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">socketio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">On</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">socketio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">EventMessage</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ep </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">socketio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">EventPayload</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ep</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Kws</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Emit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token function" style="color:#d73a49">byte</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello back!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> socketio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TextMessage</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/ws/:id"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> socketio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">kws </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">socketio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Websocket</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="circuit-breaker">Circuit Breaker<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#circuit-breaker" class="hash-link" aria-label="Direct link to Circuit Breaker" title="Direct link to Circuit Breaker" translate="no">​</a></h3>
<p>Protect your app from cascading failures when upstream services are down:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/circuitbreaker"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">circuitbreaker</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">circuitbreaker</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Timeout</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">          </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Second</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    MaxRequests</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Interval</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">         </span><span class="token number" style="color:#36acaa">30</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Second</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ReadyToTrip</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">counts circuitbreaker</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Counts</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">bool</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> counts</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ConsecutiveFailures </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="load-shedding">Load Shedding<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#load-shedding" class="hash-link" aria-label="Direct link to Load Shedding" title="Direct link to Load Shedding" translate="no">​</a></h3>
<p>Reject excess traffic before it overwhelms your service:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/loadshed"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">loadshed</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">loadshed</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    MaxConcurrent</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>When your service is at capacity, new requests get 503 instead of making everything slow.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="more-contrib-packages">More Contrib Packages<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#more-contrib-packages" class="hash-link" aria-label="Direct link to More Contrib Packages" title="Direct link to More Contrib Packages" translate="no">​</a></h3>
<table><thead><tr><th>Package</th><th>Purpose</th></tr></thead><tbody><tr><td><strong>fiberzap</strong></td><td>Structured logging with Uber's Zap</td></tr><tr><td><strong>fiberzerolog</strong></td><td>Structured logging with zerolog</td></tr><tr><td><strong>fibersentry</strong></td><td>Error tracking with Sentry</td></tr><tr><td><strong>fibernewrelic</strong></td><td>APM with New Relic</td></tr><tr><td><strong>fiberi18n</strong></td><td>Internationalization support</td></tr><tr><td><strong>opafiber</strong></td><td>Policy enforcement with Open Policy Agent</td></tr><tr><td><strong>paseto</strong></td><td>PASETO token authentication (alternative to JWT)</td></tr><tr><td><strong>hcaptcha</strong></td><td>hCaptcha verification</td></tr><tr><td><strong>casbin</strong></td><td>Authorization with Casbin</td></tr><tr><td><strong>fgprof</strong></td><td>Full goroutine profiling</td></tr><tr><td><strong>monitor</strong></td><td>Real-time server metrics dashboard</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="core-vs-contrib-how-to-decide">Core vs. Contrib: How to Decide<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#core-vs-contrib-how-to-decide" class="hash-link" aria-label="Direct link to Core vs. Contrib: How to Decide" title="Direct link to Core vs. Contrib: How to Decide" translate="no">​</a></h2>
<ul>
<li class="">If it has <strong>no external Go dependencies</strong> → it is in core (<code>github.com/gofiber/fiber/v3/middleware/...</code>)</li>
<li class="">If it <strong>requires external libraries</strong> → it is in contrib (<code>github.com/gofiber/contrib/...</code>)</li>
</ul>
<p>This split keeps your binary small. If you build an API that does not use JWT, you do not pull in the JWT library and its transitive dependencies.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="v3-support">v3 Support<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#v3-support" class="hash-link" aria-label="Direct link to v3 Support" title="Direct link to v3 Support" translate="no">​</a></h2>
<p>For Fiber v3, the contrib packages use a dedicated v3 base path. All v3-compatible imports start with <code>github.com/gofiber/contrib/v3/</code>:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Fiber v3 import path</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> jwtware </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/jwt"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/websocket"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/otelfiber"</span><br></div></code></pre></div></div>
<p>The documentation shows the <code>v3_</code> prefix in versioning to indicate Fiber v3 compatibility. Check each package's documentation page for the exact import path.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-contrib-packages#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/contrib/">Contrib Documentation</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/contrib/jwt/">JWT Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/contrib/websocket/">WebSocket</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/contrib/otelfiber/">OpenTelemetry</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/contrib/swagger/">Swagger</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/contrib/socketio/">Socket.io</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>contrib</category>
            <category>jwt</category>
            <category>websocket</category>
            <category>opentelemetry</category>
            <category>swagger</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Template Engines]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-template-engines</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-template-engines</guid>
            <pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[9 template engines, one interface  -  pick your syntax and start rendering. From Go's html/template to Pug, Django, and Handlebars.]]></description>
            <content:encoded><![CDATA[<p>Not every project is a JSON API. Sometimes you need to render HTML  -  a landing page, an admin panel, an email template, a server-rendered app. Fiber supports 9 template engines through a single <code>Views</code> interface, so you pick the syntax you like and Fiber handles the rest.</p>
<p>The surprising part is not the number of engines. It is that switching from one engine to another requires changing exactly two lines of code: the import and the engine constructor. Your handlers, layouts, and rendering calls stay the same.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-views-interface">The Views Interface<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#the-views-interface" class="hash-link" aria-label="Direct link to The Views Interface" title="Direct link to The Views Interface" translate="no">​</a></h2>
<p>Every template engine implements Fiber's <code>Views</code> interface. Your handlers call <code>c.Render()</code> and Fiber delegates to whatever engine you configured:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"index"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"Title"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Welcome"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"Items"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> items</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This handler works identically whether you are using HTML templates, Pug, Django, or any other engine. The engine is configured once at startup and never referenced in handler code.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-9-engines">The 9 Engines<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#the-9-engines" class="hash-link" aria-label="Direct link to The 9 Engines" title="Direct link to The 9 Engines" translate="no">​</a></h2>
<table><thead><tr><th>Engine</th><th>Syntax Style</th><th>Best For</th></tr></thead><tbody><tr><td><strong>html</strong></td><td>Go's <code>html/template</code></td><td>Go developers, maximum control</td></tr><tr><td><strong>django</strong></td><td><code>{% block %}</code> / <code>{{ var }}</code></td><td>Python developers, designers</td></tr><tr><td><strong>pug</strong></td><td>Indentation-based, minimal</td><td>Clean markup, rapid prototyping</td></tr><tr><td><strong>handlebars</strong></td><td><code>{{#each}}</code> / <code>{{&gt; partial}}</code></td><td>JavaScript developers</td></tr><tr><td><strong>mustache</strong></td><td>Logic-less <code>{{var}}</code></td><td>Simple templates, emails</td></tr><tr><td><strong>jet</strong></td><td>Go-native, fast</td><td>Performance-critical rendering</td></tr><tr><td><strong>amber</strong></td><td>HAML-like, Go functions</td><td>Ruby developers</td></tr><tr><td><strong>ace</strong></td><td>Indentation-based, Go funcs</td><td>Clean Go-native templates</td></tr><tr><td><strong>slim</strong></td><td>Minimal whitespace syntax</td><td>Ruby/Slim developers</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="quick-start-with-htmltemplate">Quick Start with html/template<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#quick-start-with-htmltemplate" class="hash-link" aria-label="Direct link to Quick Start with html/template" title="Direct link to Quick Start with html/template" translate="no">​</a></h2>
<p>The most common choice  -  Go's built-in template engine with Fiber integration:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/template/html/v2"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Point to your template directory and file extension</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    engine </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> html</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./views"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">".html"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Views</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> engine</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"index"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"Title"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"My App"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Listen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">":3000"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>With a template file at <code>./views/index.html</code>:</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token doctype punctuation" style="color:#393A34;font-style:italic">&lt;!</span><span class="token doctype doctype-tag" style="color:#999988;font-style:italic">DOCTYPE</span><span class="token doctype" style="color:#999988;font-style:italic"> </span><span class="token doctype name" style="color:#999988;font-style:italic">html</span><span class="token doctype punctuation" style="color:#393A34;font-style:italic">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">html</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">head</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">title</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain">{{.Title}}</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">title</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">head</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">body</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">h1</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain">{{.Title}}</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">h1</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">body</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">html</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-layouts">Using Layouts<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#using-layouts" class="hash-link" aria-label="Direct link to Using Layouts" title="Direct link to Using Layouts" translate="no">​</a></h2>
<p>Layouts let you define a shared structure (header, footer, navigation) and inject page content into it:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"index"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"Title"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Home"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"layouts/main"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The layout file <code>./views/layouts/main.html</code>:</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token doctype punctuation" style="color:#393A34;font-style:italic">&lt;!</span><span class="token doctype doctype-tag" style="color:#999988;font-style:italic">DOCTYPE</span><span class="token doctype" style="color:#999988;font-style:italic"> </span><span class="token doctype name" style="color:#999988;font-style:italic">html</span><span class="token doctype punctuation" style="color:#393A34;font-style:italic">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">html</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">head</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">title</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain">{{.Title}}</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">title</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">head</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">body</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">nav</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token comment" style="color:#999988;font-style:italic">&lt;!-- shared navigation --&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">nav</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    {{embed}}</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">footer</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token comment" style="color:#999988;font-style:italic">&lt;!-- shared footer --&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">footer</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">body</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">html</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><br></div></code></pre></div></div>
<p>The <code>{{embed}}</code> tag marks where the page content is inserted. The page template (<code>index.html</code>) contains only the page-specific content.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="switching-engines">Switching Engines<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#switching-engines" class="hash-link" aria-label="Direct link to Switching Engines" title="Direct link to Switching Engines" translate="no">​</a></h2>
<p>Want to use Pug instead of HTML templates? Change two lines:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/template/pug/v2"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">engine </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> pug</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./views"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">".pug"</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Your handlers stay the same. Your layouts stay the same. Only the template files and the engine constructor change.</p>
<p>A Pug template for the same page:</p>
<div class="language-pug codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-pug codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">h1= Title</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">p Welcome to #{Title}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="development-features">Development Features<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#development-features" class="hash-link" aria-label="Direct link to Development Features" title="Direct link to Development Features" translate="no">​</a></h2>
<p>Every engine supports features that make development easier:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">engine </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> html</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./views"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">".html"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Reload templates on every request (development only)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">engine</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Reload</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Print parsed template names for debugging</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">engine</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Debug</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Add custom template functions</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">engine</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">AddFunc</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"upper"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> strings</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ToUpper</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">engine</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">AddFunc</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"formatDate"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Time</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> t</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Format</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"2006-01-02"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><code>Reload(true)</code> is essential during development  -  without it, you need to restart the server to see template changes. Disable it in production for performance.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="embedding-templates-in-the-binary">Embedding Templates in the Binary<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#embedding-templates-in-the-binary" class="hash-link" aria-label="Direct link to Embedding Templates in the Binary" title="Direct link to Embedding Templates in the Binary" translate="no">​</a></h2>
<p>For production deployments, you can embed templates into your Go binary using <code>embed.FS</code>:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"embed"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//go:embed views/*</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> viewsFS embed</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">FS</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">engine </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> html</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewFileSystem</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FS</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">viewsFS</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">".html"</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This eliminates the need to ship template files alongside your binary. The templates are compiled into the executable, making deployment a single file copy.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-to-use-which-engine">When to Use Which Engine<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#when-to-use-which-engine" class="hash-link" aria-label="Direct link to When to Use Which Engine" title="Direct link to When to Use Which Engine" translate="no">​</a></h2>
<ul>
<li class=""><strong>Building a Go-native app?</strong> Use <code>html</code>  -  it is the standard, has the best tooling support, and is fast.</li>
<li class=""><strong>Working with frontend developers who know Django/Jinja2?</strong> Use <code>django</code>  -  the syntax is familiar.</li>
<li class=""><strong>Need clean, minimal markup?</strong> Use <code>pug</code>  -  indentation-based syntax reduces boilerplate.</li>
<li class=""><strong>Rendering emails or simple content?</strong> Use <code>mustache</code>  -  logic-less templates force separation of concerns.</li>
<li class=""><strong>Maximum rendering performance?</strong> Use <code>jet</code>  -  benchmarks show it is consistently fast.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-template-engines#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/template/">Template Documentation</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/guide/templates">Templates Guide</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/template/html/">HTML Engine</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/template/django/">Django Engine</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/template/pug/">Pug Engine</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>templates</category>
            <category>html</category>
            <category>pug</category>
            <category>django</category>
            <category>handlebars</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Storage Packages]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-storage-packages</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-storage-packages</guid>
            <pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[One interface, 30+ backends  -  how Fiber's storage packages let you swap databases without changing a single line of middleware code.]]></description>
            <content:encoded><![CDATA[<p>Every Fiber middleware that needs to persist data  -  sessions, rate limiter counters, cache entries, CSRF tokens  -  uses the same <code>Storage</code> interface. That means you can swap from in-memory storage to Redis to Postgres to DynamoDB by changing one line of configuration. Your middleware code stays exactly the same.</p>
<p>Most developers discover this the hard way: they build with the default in-memory storage, deploy to production, and realize their rate limiter resets on every restart and their sessions vanish during rolling deployments. The fix is not a rewrite  -  it is a one-line storage swap.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-storage-interface">The Storage Interface<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#the-storage-interface" class="hash-link" aria-label="Direct link to The Storage Interface" title="Direct link to The Storage Interface" translate="no">​</a></h2>
<p>Every storage driver implements the same interface:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> Storage </span><span class="token keyword" style="color:#00009f">interface</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">byte</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> val </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">byte</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> exp time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Duration</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Delete</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Reset</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Close</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Five methods. That is the entire contract. Any middleware that accepts a <code>Storage</code> field works with any driver that implements this interface. No adapters, no wrappers, no glue code.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="30-storage-drivers">30+ Storage Drivers<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#30-storage-drivers" class="hash-link" aria-label="Direct link to 30+ Storage Drivers" title="Direct link to 30+ Storage Drivers" translate="no">​</a></h2>
<p>The <a href="https://github.com/gofiber/storage" target="_blank" rel="noopener noreferrer" class="">gofiber/storage</a> repository includes drivers for:</p>
<p><strong>Key-Value Stores</strong>: Redis, Valkey, Rueidis, Memcache, Badger, Bbolt, Pebble, LevelDB, Ristretto, Etcd, NATS</p>
<p><strong>SQL Databases</strong>: Postgres, MySQL, MSSQL, SQLite3</p>
<p><strong>Cloud Services</strong>: DynamoDB, S3, Azure Blob, Cloudflare KV, Firestore, Minio</p>
<p><strong>NoSQL / Document</strong>: MongoDB, ArangoDB, Couchbase, SurrealDB, Neo4j</p>
<p><strong>Specialized</strong>: Aerospike, Cassandra, ScyllaDB, ClickHouse, Coherence, Memory</p>
<p>Every driver is tested against the latest two Go versions and has CI badges showing test status.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="picking-the-right-storage">Picking the Right Storage<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#picking-the-right-storage" class="hash-link" aria-label="Direct link to Picking the Right Storage" title="Direct link to Picking the Right Storage" translate="no">​</a></h2>
<p>The choice depends on your deployment:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="single-server-simple-app--sqlite3">Single Server, Simple App → SQLite3<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#single-server-simple-app--sqlite3" class="hash-link" aria-label="Direct link to Single Server, Simple App → SQLite3" title="Direct link to Single Server, Simple App → SQLite3" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/sqlite3/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> sqlite3</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sqlite3</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Database</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./fiber_data.db"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>No external dependencies. Survives restarts. Fast enough for most workloads. If your app runs on one server and you do not want to manage Redis, this is your answer.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="multiple-servers-production--redis">Multiple Servers, Production → Redis<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#multiple-servers-production--redis" class="hash-link" aria-label="Direct link to Multiple Servers, Production → Redis" title="Direct link to Multiple Servers, Production → Redis" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/redis/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Host</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"redis.internal"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">6379</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Password</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"REDIS_PASSWORD"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Database</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Redis is the production default for a reason: fast, shared across instances, supports TTL natively, and you probably already have one running for caching.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="already-using-postgres--postgres">Already Using Postgres → Postgres<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#already-using-postgres--postgres" class="hash-link" aria-label="Direct link to Already Using Postgres → Postgres" title="Direct link to Already Using Postgres → Postgres" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/postgres/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> postgres</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">postgres</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Host</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"db.internal"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">5432</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Username</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"app"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Password</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"DB_PASSWORD"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Database</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"myapp"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Table</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"fiber_storage"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>If your app already connects to Postgres, adding a <code>fiber_storage</code> table avoids a new infrastructure dependency. The driver creates the table automatically on first use.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="aws--serverless--dynamodb">AWS / Serverless → DynamoDB<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#aws--serverless--dynamodb" class="hash-link" aria-label="Direct link to AWS / Serverless → DynamoDB" title="Direct link to AWS / Serverless → DynamoDB" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/dynamodb/v2"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> dynamodb</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">dynamodb</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Table</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"fiber-sessions"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>For serverless or AWS-native deployments, DynamoDB scales without management and integrates with IAM for authentication.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="development--testing--memory">Development / Testing → Memory<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#development--testing--memory" class="hash-link" aria-label="Direct link to Development / Testing → Memory" title="Direct link to Development / Testing → Memory" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/memory/v2"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> memory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Fast, zero config, no persistence. Use this for tests and local development where data loss on restart is fine.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-storage-with-middleware">Using Storage with Middleware<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#using-storage-with-middleware" class="hash-link" aria-label="Direct link to Using Storage with Middleware" title="Direct link to Using Storage with Middleware" translate="no">​</a></h2>
<p>Once you have a store, pass it to any middleware that accepts a <code>Storage</code> field:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">Host</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"localhost"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6379</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Rate limiter  -  shared counters across instances</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Storage</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    store</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Cache  -  shared cache across instances</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">   </span><span class="token number" style="color:#36acaa">30</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Storage</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      store</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Sessions  -  persistent across restarts</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sessionStore </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Storage</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> store</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sessionStore</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Handler</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Three middleware, one storage backend, zero code changes when you switch from Redis to Postgres.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="swapping-storage-without-code-changes">Swapping Storage Without Code Changes<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#swapping-storage-without-code-changes" class="hash-link" aria-label="Direct link to Swapping Storage Without Code Changes" title="Direct link to Swapping Storage Without Code Changes" translate="no">​</a></h2>
<p>A common pattern is to select the storage backend from an environment variable:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">newStorage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Storage </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">switch</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"STORAGE_BACKEND"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"redis"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            Host</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"REDIS_HOST"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6379</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"postgres"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> postgres</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">postgres</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            ConnectionURI</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"DATABASE_URL"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">default</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> memory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This lets you run with in-memory storage locally and Redis in production without changing any middleware configuration.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="benchmarks">Benchmarks<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#benchmarks" class="hash-link" aria-label="Direct link to Benchmarks" title="Direct link to Benchmarks" translate="no">​</a></h2>
<p>Storage benchmarks are published at <a href="https://gofiber.github.io/storage/benchmarks" target="_blank" rel="noopener noreferrer" class="">gofiber.github.io/storage/benchmarks</a>. Before picking a backend for a high-throughput use case, check the numbers. The short version: Redis and Memory are fastest for reads, SQLite3 is surprisingly competitive for single-server workloads, and cloud-based stores (DynamoDB, S3) add network latency but scale infinitely.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If you are using default in-memory storage in production, switch to Redis or SQLite3 today. It is a one-line change that prevents data loss on restart and makes your rate limiters and sessions work correctly across deployments.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-storage-packages#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/storage/">Storage Packages Documentation</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/session">Session Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/limiter">Limiter Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/cache">Cache Middleware</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>storage</category>
            <category>redis</category>
            <category>postgres</category>
            <category>sqlite</category>
            <category>database</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Sessions in v3]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-sessions-cookies</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-sessions-cookies</guid>
            <pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[What changed and why your old patterns won't work  -  the new middleware-based approach, storage backends, and cookie settings that actually matter.]]></description>
            <content:encoded><![CDATA[<p>If you used sessions in Fiber v2, forget everything. Fiber v3 replaced the session system entirely. The store-based API is gone. Sessions are now middleware  -  you register them once and they are available on every request through the context.</p>
<p>This sounds like a small change. It is not. The new approach changes how you initialize sessions, how you access them in handlers, and how you handle the interaction between sessions and other middleware like CSRF. If you migrate without understanding the new model, you will spend hours debugging session data that silently disappears.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-old-way-vs-the-new-way">The Old Way vs. The New Way<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#the-old-way-vs-the-new-way" class="hash-link" aria-label="Direct link to The Old Way vs. The New Way" title="Direct link to The Old Way vs. The New Way" translate="no">​</a></h2>
<p>In Fiber v2, you created a session store and manually got/saved sessions in every handler:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// v2 pattern  -  no longer works in v3</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> store</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    name </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"name"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Save</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>In v3, sessions are middleware. You register the store once, and sessions are automatically loaded and saved:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// v3 pattern</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sessionStore </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sessionStore</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Handler</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"name"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// No manual Save() needed  -  the middleware handles it</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The key differences:</p>
<ul>
<li class=""><strong>Middleware-based</strong>: Register once with <code>app.Use()</code>, not per-handler</li>
<li class=""><strong>Automatic lifecycle</strong>: Sessions are loaded before your handler and saved after</li>
<li class=""><strong>Context access</strong>: Use <code>session.FromContext(c)</code> instead of <code>store.Get(c)</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="configuring-the-session-store">Configuring the Session Store<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#configuring-the-session-store" class="hash-link" aria-label="Direct link to Configuring the Session Store" title="Direct link to Configuring the Session Store" translate="no">​</a></h2>
<p>The session store controls cookie behavior and storage backend:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">sessionStore </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token string" style="color:#e3116c">"__Host-session"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSecure</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieHTTPOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSameSite</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Lax"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSessionOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Cookie expires when browser closes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    IdleTimeout</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">       </span><span class="token number" style="color:#36acaa">30</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cookie-name-use-the-__host--prefix">Cookie Name: Use the __Host- Prefix<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#cookie-name-use-the-__host--prefix" class="hash-link" aria-label="Direct link to Cookie Name: Use the __Host- Prefix" title="Direct link to Cookie Name: Use the __Host- Prefix" translate="no">​</a></h3>
<p>The <code>__Host-</code> prefix is a browser security feature. Browsers enforce that cookies with this prefix:</p>
<ul>
<li class="">Must have <code>Secure</code> set to <code>true</code></li>
<li class="">Must not have a <code>Domain</code> attribute (scoped to the exact host)</li>
<li class="">Must have <code>Path</code> set to <code>/</code></li>
</ul>
<p>This prevents subdomain cookie injection attacks. If an attacker controls <code>evil.example.com</code>, they cannot set a cookie for <code>app.example.com</code> when the <code>__Host-</code> prefix is used.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cookiehttponly-almost-always-true">CookieHTTPOnly: Almost Always True<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#cookiehttponly-almost-always-true" class="hash-link" aria-label="Direct link to CookieHTTPOnly: Almost Always True" title="Direct link to CookieHTTPOnly: Almost Always True" translate="no">​</a></h3>
<p>Set this to <code>true</code> unless your JavaScript needs to read the session cookie. For sessions, there is almost never a reason for JavaScript to access the session ID  -  the browser sends it automatically with every request.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="idletimeout-vs-absolutetimeout">IdleTimeout vs. AbsoluteTimeout<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#idletimeout-vs-absolutetimeout" class="hash-link" aria-label="Direct link to IdleTimeout vs. AbsoluteTimeout" title="Direct link to IdleTimeout vs. AbsoluteTimeout" translate="no">​</a></h3>
<p>Two different timeout concepts:</p>
<ul>
<li class=""><strong>IdleTimeout</strong>: How long a session survives without activity. Each request resets the timer. Default: 30 minutes.</li>
<li class=""><strong>AbsoluteTimeout</strong>: Maximum session lifetime regardless of activity. Default: 0 (no absolute limit).</li>
</ul>
<p>For a typical web app:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">sessionStore </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    IdleTimeout</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      </span><span class="token number" style="color:#36acaa">30</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Inactive users get logged out</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AbsoluteTimeout</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">24</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Hour</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Everyone gets logged out after 24h</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The absolute timeout is important for security. Without it, a session that stays active forever is a session that can be stolen forever.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="storage-backends">Storage Backends<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#storage-backends" class="hash-link" aria-label="Direct link to Storage Backends" title="Direct link to Storage Backends" translate="no">​</a></h2>
<p>By default, sessions are stored in memory. This works for development but fails in production for two reasons: memory fills up, and sessions are lost on restart.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="redis-----the-production-default">Redis  -  The Production Default<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#redis-----the-production-default" class="hash-link" aria-label="Direct link to Redis  -  The Production Default" title="Direct link to Redis  -  The Production Default" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/redis/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">storage </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Host</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"localhost"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">6379</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Password</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Database</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sessionStore </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Storage</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> storage</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Redis is the natural choice: fast, persistent across restarts, and supports TTL natively. If you are already using Redis for caching, reuse the same instance with a different database number.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="sqlite-----for-small-apps">SQLite  -  For Small Apps<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#sqlite-----for-small-apps" class="hash-link" aria-label="Direct link to SQLite  -  For Small Apps" title="Direct link to SQLite  -  For Small Apps" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/sqlite3/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">storage </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> sqlite3</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sqlite3</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Database</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./sessions.db"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>SQLite works well for single-server deployments where you do not want to run Redis. Sessions survive restarts, and the performance is sufficient for small to medium traffic.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="postgres-or-mysql-----when-you-already-have-one">Postgres or MySQL  -  When You Already Have One<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#postgres-or-mysql-----when-you-already-have-one" class="hash-link" aria-label="Direct link to Postgres or MySQL  -  When You Already Have One" title="Direct link to Postgres or MySQL  -  When You Already Have One" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/postgres/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">storage </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> postgres</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">postgres</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Host</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"localhost"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">5432</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Username</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"app"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Password</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"secret"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Database</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"myapp"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Table</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"sessions"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>If your app already connects to Postgres or MySQL, using it for sessions avoids adding another infrastructure dependency.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="session--csrf-the-order-that-matters">Session + CSRF: The Order That Matters<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#session--csrf-the-order-that-matters" class="hash-link" aria-label="Direct link to Session + CSRF: The Order That Matters" title="Direct link to Session + CSRF: The Order That Matters" translate="no">​</a></h2>
<p>When using sessions with CSRF protection, the session middleware must come before CSRF:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Correct order</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sessionStore</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Handler</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Sessions first</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Session</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> sessionStore</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token comment" style="color:#999988;font-style:italic">// CSRF uses the session store</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>CSRF in session mode stores the CSRF token inside the user's session. If the session middleware has not run yet, CSRF cannot access the session and token validation fails silently.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="working-with-session-data">Working with Session Data<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#working-with-session-data" class="hash-link" aria-label="Direct link to Working with Session Data" title="Direct link to Working with Session Data" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-values">Setting Values<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#setting-values" class="hash-link" aria-label="Direct link to Setting Values" title="Direct link to Setting Values" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/login"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"userID"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ID</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"role"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Role</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"loginAt"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Unix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Redirect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">To</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/dashboard"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="getting-values">Getting Values<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#getting-values" class="hash-link" aria-label="Direct link to Getting Values" title="Direct link to Getting Values" translate="no">​</a></h3>
<p>Session values are stored as <code>any</code>, so you need type assertions:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/dashboard"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    userID</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ok </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"userID"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">uint64</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">ok </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Redirect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">To</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/login"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"userID"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> userID</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="destroying-sessions-logout">Destroying Sessions (Logout)<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#destroying-sessions-logout" class="hash-link" aria-label="Direct link to Destroying Sessions (Logout)" title="Direct link to Destroying Sessions (Logout)" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/logout"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Destroy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Redirect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">To</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/login"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><code>Destroy()</code> removes all session data from storage and clears the session cookie. After calling <code>Destroy()</code>, any subsequent <code>sess.Get()</code> calls in the same request return <code>nil</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="regenerating-session-ids">Regenerating Session IDs<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#regenerating-session-ids" class="hash-link" aria-label="Direct link to Regenerating Session IDs" title="Direct link to Regenerating Session IDs" translate="no">​</a></h3>
<p>After authentication state changes  -  login, logout, privilege escalation  -  regenerate the session ID to prevent session fixation attacks:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/login"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Authenticate user...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Regenerate session ID to prevent fixation</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Regenerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"userID"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ID</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Redirect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">To</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/dashboard"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This creates a new session ID while preserving the existing session data. The old session ID becomes invalid.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-middleware-you-should-pair-with-sessions">The Middleware You Should Pair with Sessions<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#the-middleware-you-should-pair-with-sessions" class="hash-link" aria-label="Direct link to The Middleware You Should Pair with Sessions" title="Direct link to The Middleware You Should Pair with Sessions" translate="no">​</a></h2>
<p>Sessions rarely work alone. Here is the typical middleware stack for an authenticated app:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 1. Security headers</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 2. Sessions  -  before anything that needs auth state</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sessionStore</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Handler</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 3. CSRF  -  uses session store</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Session</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        sessionStore</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSecure</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">   </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieHTTPOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 4. Auth middleware  -  checks session for user</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">authMiddleware</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 5. Routes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/dashboard"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dashboardHandler</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The order is not arbitrary. Each layer depends on the one above it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If you are migrating from v2 sessions, start by switching to the middleware pattern. Register <code>sessionStore.Handler()</code> early in your middleware stack, replace all <code>store.Get(c)</code> calls with <code>session.FromContext(c)</code>, and remove manual <code>sess.Save()</code> calls. The middleware handles saving automatically.</p>
<p>If you are starting fresh, use Redis as your storage backend and set up the <code>__Host-</code> cookie prefix from day one. These two decisions prevent the most common session-related production issues.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-sessions-cookies#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/session">Session Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/csrf">CSRF Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/encryptcookie">Encrypt Cookie Middleware</a></li>
<li class=""><a href="https://github.com/gofiber/storage" target="_blank" rel="noopener noreferrer" class="">Storage Packages</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>sessions</category>
            <category>cookies</category>
            <category>state</category>
            <category>middleware</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[File Uploads]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-file-uploads</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-file-uploads</guid>
            <pubDate>Tue, 05 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The parts every tutorial skips  -  size limits, type validation, path traversal prevention, and the storage patterns that keep your server alive.]]></description>
            <content:encoded><![CDATA[<p>The typical file upload tutorial is five lines: parse the form, get the file, save it to disk. It works for a homework assignment. It fails the moment someone uploads a 2GB file, or a <code>.exe</code> renamed to <code>.jpg</code>, or a thousand files simultaneously.</p>
<p>Production file handling needs three things the tutorials skip: size limits that protect your server, type validation that goes beyond the extension, and storage patterns that do not block your event loop.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="single-file-upload">Single File Upload<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#single-file-upload" class="hash-link" aria-label="Direct link to Single File Upload" title="Direct link to Single File Upload" translate="no">​</a></h2>
<p>The basic pattern is straightforward. Fiber parses multipart forms and gives you a <code>*multipart.FileHeader</code>:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/upload"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FormFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"document"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"No file uploaded"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Save to disk</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    err </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SaveFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sprintf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./uploads/%s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Filename</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusInternalServerError</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to save file"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"filename"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Filename</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"size"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Size</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This works but has problems. The filename comes from the client  -  it could contain path traversal characters like <code>../</code>. The file could be any size. The file could be anything, not just a document.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="never-trust-the-filename">Never Trust the Filename<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#never-trust-the-filename" class="hash-link" aria-label="Direct link to Never Trust the Filename" title="Direct link to Never Trust the Filename" translate="no">​</a></h2>
<p>The first rule of file uploads: never use the client's filename directly. A malicious client can send a filename like <code>../../etc/passwd</code> or <code>../../../app/config.yaml</code>.</p>
<p>Generate your own filenames. This example uses <code>github.com/google/uuid</code> - install it with <code>go get github.com/google/uuid</code>:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"fmt"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"path/filepath"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/google/uuid"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/upload"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FormFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"avatar"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"No file uploaded"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Generate a safe filename</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ext </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Ext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Filename</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    safeName </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sprintf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"%s%s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> uuid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">String</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ext</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    savePath </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./uploads"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> safeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SaveFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> savePath</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"path"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> safeName</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-body-limits">Setting Body Limits<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#setting-body-limits" class="hash-link" aria-label="Direct link to Setting Body Limits" title="Direct link to Setting Body Limits" translate="no">​</a></h2>
<p>By default, Fiber (via fasthttp) allows request bodies up to 4MB. For file uploads, you probably want to change this:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    BodyLimit</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">50</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1024</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1024</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 50MB</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>When a client sends a body larger than this limit, Fiber returns <code>413 Request Entity Too Large</code> automatically. No parsing, no disk usage, no memory allocation for the oversized body.</p>
<p>For different limits on different routes, use the <code>limiter</code> approach:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Small limit for API routes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">api </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Group</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/api"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Request</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ContentLength</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">1024</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">1024</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ErrRequestEntityTooLarge</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Larger limit for upload routes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/upload"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> uploadHandler</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="validating-file-types">Validating File Types<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#validating-file-types" class="hash-link" aria-label="Direct link to Validating File Types" title="Direct link to Validating File Types" translate="no">​</a></h2>
<p>The file extension means nothing  -  anyone can rename a file. Check the actual content by reading the first bytes and detecting the MIME type:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"net/http"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">validateFileType</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">multipart</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">FileHeader</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> allowed </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    f</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Open</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">defer</span><span class="token plain"> f</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Close</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Read the first 512 bytes for MIME detection</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    buf </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">byte</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">512</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    n</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> f</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Read</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buf</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    mimeType </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">DetectContentType</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">buf</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">range</span><span class="token plain"> allowed </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> mimeType </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> a </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Errorf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"file type %s is not allowed"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> mimeType</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Use it in your handler:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/avatar"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FormFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"avatar"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"No file uploaded"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Only allow images</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    allowed </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"image/jpeg"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"image/png"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"image/webp"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">validateFileType</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> allowed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Only JPEG, PNG, and WebP images are allowed"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    safeName </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sprintf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"%s%s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> uuid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">String</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Ext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Filename</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SaveFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./uploads"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> safeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><code>http.DetectContentType</code> uses the first 512 bytes of the file to determine the MIME type based on the file's magic bytes. It is not foolproof  -  a determined attacker can craft files that pass detection  -  but it blocks casual misuse and accidental uploads of wrong file types.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="multiple-file-uploads">Multiple File Uploads<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#multiple-file-uploads" class="hash-link" aria-label="Direct link to Multiple File Uploads" title="Direct link to Multiple File Uploads" translate="no">​</a></h2>
<p>Fiber handles multiple files from the same form field:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/gallery"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    form</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">MultipartForm</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Invalid form data"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    files </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> form</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">File</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"photos"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">len</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">files</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"No photos uploaded"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">len</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">files</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Maximum 10 photos allowed"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> saved </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> file </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">range</span><span class="token plain"> files </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        safeName </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sprintf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"%s%s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> uuid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">String</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Ext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Filename</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        savePath </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./uploads/gallery"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> safeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SaveFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> savePath</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        saved </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">saved</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> safeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"uploaded"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">len</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">saved</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"files"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    saved</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Always limit the number of files. Without a count limit, a client could send thousands of files in a single request and exhaust your disk I/O.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="mixed-file-and-data-uploads">Mixed File and Data Uploads<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#mixed-file-and-data-uploads" class="hash-link" aria-label="Direct link to Mixed File and Data Uploads" title="Direct link to Mixed File and Data Uploads" translate="no">​</a></h2>
<p>Often you need metadata alongside the file  -  a title, description, or category:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> DocumentUpload </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Title    </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`form:"title"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Category </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`form:"category"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/documents"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> meta DocumentUpload</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Bind</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Body</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">meta</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Invalid form data"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FormFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"file"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"No file uploaded"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    safeName </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sprintf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"%s%s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> uuid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">String</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Ext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Filename</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SaveFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./uploads"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> safeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"title"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    meta</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Title</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"category"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> meta</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Category</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"file"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     safeName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"size"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Size</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The client sends a <code>multipart/form-data</code> request with both form fields and file parts. Fiber's binding handles the form fields, and <code>FormFile</code> handles the file.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cleaning-up-on-error">Cleaning Up on Error<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#cleaning-up-on-error" class="hash-link" aria-label="Direct link to Cleaning Up on Error" title="Direct link to Cleaning Up on Error" translate="no">​</a></h2>
<p>If saving to database fails after the file is written to disk, you have an orphaned file. Clean up explicitly:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/upload"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FormFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"file"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"No file uploaded"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    safeName </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sprintf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"%s%s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> uuid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">String</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Ext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Filename</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    savePath </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> filepath</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./uploads"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> safeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SaveFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> savePath</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Try to save metadata to database</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> db</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SaveFileRecord</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">safeName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Size</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Clean up the file we just saved</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Remove</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">savePath</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"file"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> safeName</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This pattern prevents disk space from filling up with files that have no database record pointing to them.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If your current upload handler uses the client filename directly, fix that first  -  it is a path traversal vulnerability. Then add body limits and file type validation. These three changes cover the most common attack vectors and the most common production incidents.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-file-uploads#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/api/ctx#formfile">Ctx FormFile</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/api/ctx#multipartform">Ctx MultipartForm</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/api/ctx#savefile">Ctx SaveFile</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/api/bind">Bind</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>file-upload</category>
            <category>multipart</category>
            <category>streaming</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Prefork Mode]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-prefork-mode</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-prefork-mode</guid>
            <pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How Fiber runs like Nginx  -  fork multiple processes with one line of config. When it helps, when it makes things worse.]]></description>
            <content:encoded><![CDATA[<p>Most Go developers know that Go uses goroutines for concurrency. A single process handles thousands of connections by scheduling goroutines across OS threads. That is usually enough.</p>
<p>But Fiber has a trick that most Go frameworks do not: prefork mode. One line of config, and Fiber spawns multiple OS processes, each with its own event loop, all listening on the same port. It is the same pattern that Nginx and Node.js cluster mode use.</p>
<p>The surprise is not that Fiber supports this. The surprise is when it actually helps  -  and when it makes your app slower.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-prefork-does">What Prefork Does<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#what-prefork-does" class="hash-link" aria-label="Direct link to What Prefork Does" title="Direct link to What Prefork Does" translate="no">​</a></h2>
<p>In normal mode, Fiber runs one process with one <code>fasthttp</code> server. That server uses goroutines to handle concurrent requests. It works well for most workloads.</p>
<p>In prefork mode, Fiber uses <code>SO_REUSEPORT</code> (on Linux) to let multiple processes bind to the same port. The kernel distributes incoming connections across the processes:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Listen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">":3000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ListenConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    EnablePrefork</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>That is it. One setting in <code>ListenConfig</code>. Fiber detects the number of CPU cores and spawns that many child processes. Each child is a full copy of your application with its own memory space.</p>
<p>Note: In Fiber v2, this was <code>fiber.Config{Prefork: true}</code>. In v3, it moved to <code>ListenConfig</code> as <code>EnablePrefork</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-it-works-under-the-hood">How It Works Under the Hood<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#how-it-works-under-the-hood" class="hash-link" aria-label="Direct link to How It Works Under the Hood" title="Direct link to How It Works Under the Hood" translate="no">​</a></h2>
<p>When you start a preforked Fiber app:</p>
<ol>
<li class="">The <strong>master process</strong> starts and detects it is the parent.</li>
<li class="">It forks <code>runtime.GOMAXPROCS(0)</code> child processes (typically one per CPU core).</li>
<li class="">Each <strong>child process</strong> creates its own <code>fasthttp</code> server and binds to the same port.</li>
<li class="">The kernel's <code>SO_REUSEPORT</code> distributes incoming connections across children.</li>
<li class="">The master monitors children and restarts them if they crash.</li>
</ol>
<p>Each child is an independent OS process with its own Go runtime, its own goroutine scheduler, and its own memory. There is no shared state between children.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-it-actually-helps">When It Actually Helps<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#when-it-actually-helps" class="hash-link" aria-label="Direct link to When It Actually Helps" title="Direct link to When It Actually Helps" translate="no">​</a></h2>
<p>Prefork mode helps in a very specific scenario: <strong>CPU-bound workloads that saturate the Go scheduler</strong>.</p>
<p>Go's runtime scheduler is good, but it has overhead. When every request requires heavy computation  -  image processing, cryptographic operations, complex template rendering - the scheduler's lock contention becomes measurable. Prefork eliminates cross-process scheduler contention because each process has its own scheduler.</p>
<p>Benchmarks show measurable improvement (10-20% more throughput) for:</p>
<ul>
<li class="">Heavy JSON serialization/deserialization</li>
<li class="">Template rendering with complex logic</li>
<li class="">Image processing or PDF generation</li>
<li class="">Cryptographic operations per request</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-it-makes-things-worse">When It Makes Things Worse<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#when-it-makes-things-worse" class="hash-link" aria-label="Direct link to When It Makes Things Worse" title="Direct link to When It Makes Things Worse" translate="no">​</a></h2>
<p>For the vast majority of web applications  -  API servers that do database queries, call upstream services, and return JSON  -  prefork mode is neutral or harmful.</p>
<p><strong>Why it can hurt:</strong></p>
<ol>
<li class="">
<p><strong>Memory multiplication</strong>: Each child is a full process. An app that uses 100MB of memory now uses 100MB × number of cores. On a 16-core machine, that is 1.6GB just for the Go runtime and your app code.</p>
</li>
<li class="">
<p><strong>No shared state</strong>: In-memory caches, rate limiter counters, session stores  -  none of these work across prefork children. A rate limiter that allows 100 requests per minute will actually allow 100 × number of children because each child has its own counter.</p>
</li>
<li class="">
<p><strong>Connection pool multiplication</strong>: Each child opens its own database connections. If your pool is set to 20 connections and you have 8 children, that is 160 database connections. Your database might not appreciate that.</p>
</li>
<li class="">
<p><strong>I/O-bound workloads see no benefit</strong>: If your handler spends 95% of its time waiting for a database response, the CPU is mostly idle. Adding more processes to share an idle CPU does not help.</p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-shared-state-problem">The Shared State Problem<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#the-shared-state-problem" class="hash-link" aria-label="Direct link to The Shared State Problem" title="Direct link to The Shared State Problem" translate="no">​</a></h2>
<p>This is the biggest gotcha. Consider this rate limiter:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Without prefork, this allows 100 requests per IP per minute. With prefork on 8 cores, each child has its own counter, so the effective limit is 800 requests per minute.</p>
<p>The fix is to use an external store:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/redis/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Host</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"localhost"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6379</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Storage</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    store</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This applies to every middleware that maintains state: sessions, CSRF tokens, cache. If you use prefork, all stateful middleware needs an external storage backend.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="detecting-prefork-in-your-code">Detecting Prefork in Your Code<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#detecting-prefork-in-your-code" class="hash-link" aria-label="Direct link to Detecting Prefork in Your Code" title="Direct link to Detecting Prefork in Your Code" translate="no">​</a></h2>
<p>Sometimes you need to know whether you are running in the master or a child:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IsChild</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// This is a prefork child process</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Don't start background jobs, cron schedulers, etc.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// This is the master process (or non-prefork mode)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Safe to start background jobs</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This is important for background workers. If you start a cron job in your app, prefork mode would start 8 copies of it. Use <code>fiber.IsChild()</code> to only start background work in the master.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-decision-framework">The Decision Framework<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#the-decision-framework" class="hash-link" aria-label="Direct link to The Decision Framework" title="Direct link to The Decision Framework" translate="no">​</a></h2>
<p><strong>Use prefork when:</strong></p>
<ul>
<li class="">Your profiling shows CPU is the bottleneck (not I/O)</li>
<li class="">Your workload is compute-heavy per request</li>
<li class="">You already use external storage for all state (Redis, database)</li>
<li class="">You have enough memory for process multiplication</li>
</ul>
<p><strong>Do not use prefork when:</strong></p>
<ul>
<li class="">Your app is I/O-bound (most API servers)</li>
<li class="">You rely on in-memory state (rate limiters, caches, sessions)</li>
<li class="">Memory is constrained</li>
<li class="">You are running in containers with limited CPU allocation</li>
</ul>
<p><strong>The default  -  no prefork  -  is correct for most applications.</strong> Go's goroutine scheduler is highly efficient for I/O-bound work. Only switch to prefork after profiling shows that CPU scheduling is your actual bottleneck.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="measuring-the-difference">Measuring the Difference<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#measuring-the-difference" class="hash-link" aria-label="Direct link to Measuring the Difference" title="Direct link to Measuring the Difference" translate="no">​</a></h2>
<p>Before turning on prefork, establish a baseline:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Without prefork</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">go build -o app .</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">./app &amp;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">wrk -t12 -c400 -d30s http://localhost:3000/your-endpoint</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># With prefork</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">PREFORK=true ./app &amp;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">wrk -t12 -c400 -d30s http://localhost:3000/your-endpoint</span><br></div></code></pre></div></div>
<p>Compare the requests/second and latency percentiles. If prefork does not show at least a 10% improvement, the operational complexity is not worth it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-prefork-mode#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/api/app">App Configuration  -  Prefork</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/guide/faster-fiber">Make Fiber Faster</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/extra/benchmarks">Benchmarks</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>prefork</category>
            <category>performance</category>
            <category>concurrency</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Reverse Proxy Setup]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config</guid>
            <pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The three settings that break everything when you deploy Fiber behind Nginx or Traefik  -  wrong IPs, broken rate limiting, and HTTPS detection failures.]]></description>
            <content:encoded><![CDATA[<p>You deploy your Fiber app behind Nginx. Everything works  -  until you check the logs. Every request comes from <code>127.0.0.1</code>. Your rate limiter thinks all traffic is from one user. Your HTTPS redirect loop crashes the browser. And your geo-IP middleware thinks every visitor is in the same data center as your server.</p>
<p>The problem is three settings you did not configure. Fiber, by default, does not trust proxy headers  -  and it should not. But when you deploy behind a reverse proxy, you need to explicitly tell Fiber which headers to read and which proxies to trust.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-three-settings">The Three Settings<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#the-three-settings" class="hash-link" aria-label="Direct link to The Three Settings" title="Direct link to The Three Settings" translate="no">​</a></h2>
<p>Every Fiber app behind a reverse proxy needs exactly three configuration options:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">                           </span><span class="token comment" style="color:#999988;font-style:italic">// 1. Enable proxy trust</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ProxyHeader</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">HeaderXForwardedFor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token comment" style="color:#999988;font-style:italic">// 2. Which header has the real IP</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">     </span><span class="token comment" style="color:#999988;font-style:italic">// 3. Which proxies to trust</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Loopback</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Without these, <code>c.IP()</code> returns the proxy's IP address, not the client's. With them configured wrong, an attacker can forge any IP address they want.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-fiber-ignores-proxy-headers-by-default">Why Fiber Ignores Proxy Headers by Default<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#why-fiber-ignores-proxy-headers-by-default" class="hash-link" aria-label="Direct link to Why Fiber Ignores Proxy Headers by Default" title="Direct link to Why Fiber Ignores Proxy Headers by Default" translate="no">​</a></h2>
<p>When Fiber receives a request, <code>c.IP()</code> returns the remote address of the TCP connection. If the connection comes from Nginx on the same machine, that IP is <code>127.0.0.1</code>.</p>
<p>Reverse proxies add headers like <code>X-Forwarded-For</code> to carry the real client IP. But Fiber ignores these headers unless you enable <code>TrustProxy</code>. This is correct behavior  -  if Fiber blindly trusted <code>X-Forwarded-For</code>, any client could set the header directly and claim to be any IP address.</p>
<p>The trust model is: "I will read the real IP from a header, but only if the request came from a proxy I explicitly trust."</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-1-trustproxy">Setting 1: TrustProxy<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#setting-1-trustproxy" class="hash-link" aria-label="Direct link to Setting 1: TrustProxy" title="Direct link to Setting 1: TrustProxy" translate="no">​</a></h2>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">TrustProxy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<p>This is the switch that enables proxy header reading. Without it, the other settings do nothing. But this alone is not enough  -  you also need to tell Fiber which header and which proxies.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-2-proxyheader">Setting 2: ProxyHeader<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#setting-2-proxyheader" class="hash-link" aria-label="Direct link to Setting 2: ProxyHeader" title="Direct link to Setting 2: ProxyHeader" translate="no">​</a></h2>
<p>Different proxies use different headers:</p>
<table><thead><tr><th>Proxy</th><th>Header</th><th>Fiber Constant</th></tr></thead><tbody><tr><td>Nginx, HAProxy</td><td><code>X-Forwarded-For</code></td><td><code>fiber.HeaderXForwardedFor</code></td></tr><tr><td>Cloudflare</td><td><code>CF-Connecting-IP</code></td><td><code>"CF-Connecting-IP"</code></td></tr><tr><td>Fastly</td><td><code>Fastly-Client-IP</code></td><td><code>"Fastly-Client-IP"</code></td></tr><tr><td>Generic</td><td><code>X-Real-IP</code></td><td><code>"X-Real-IP"</code></td></tr></tbody></table>
<p>The most common choice is <code>X-Forwarded-For</code>, but check your proxy's documentation. Using the wrong header means <code>c.IP()</code> returns an empty string or an incorrect value.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">ProxyHeader</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">HeaderXForwardedFor</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-3-trustproxyconfig">Setting 3: TrustProxyConfig<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#setting-3-trustproxyconfig" class="hash-link" aria-label="Direct link to Setting 3: TrustProxyConfig" title="Direct link to Setting 3: TrustProxyConfig" translate="no">​</a></h2>
<p>This is where most people get it wrong. You need to specify which IPs are allowed to set the proxy header:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Specific IPs or CIDR ranges</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Proxies</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"10.10.0.58"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"192.168.0.0/24"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<p>Or use convenience flags:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Loopback</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 127.0.0.0/8, ::1/128</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Private</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">   </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    LinkLocal</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// 169.254.0.0/16, fe80::/10</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<p><strong>Use <code>Loopback: true</code></strong> when the proxy is on the same machine. <strong>Use <code>Private: true</code></strong> when the proxy is on your internal network. <strong>Use specific IPs</strong> when you know the exact proxy addresses and want maximum security.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-happens-when-you-skip-this">What Happens When You Skip This<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#what-happens-when-you-skip-this" class="hash-link" aria-label="Direct link to What Happens When You Skip This" title="Direct link to What Happens When You Skip This" translate="no">​</a></h3>
<p>If you set <code>TrustProxy: true</code> without configuring <code>TrustProxyConfig</code>, Fiber trusts nobody  -  and <code>c.IP()</code> still returns the TCP source address. The setting only works when both sides are configured.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-happens-when-you-trust-everyone">What Happens When You Trust Everyone<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#what-happens-when-you-trust-everyone" class="hash-link" aria-label="Direct link to What Happens When You Trust Everyone" title="Direct link to What Happens When You Trust Everyone" translate="no">​</a></h3>
<p>If you somehow trusted all addresses, any client could set <code>X-Forwarded-For: 1.2.3.4</code> and your app would believe them. This breaks:</p>
<ul>
<li class=""><strong>Rate limiting</strong>: An attacker rotates fake IPs to bypass limits</li>
<li class=""><strong>IP-based access control</strong>: Attackers spoof allowed IPs</li>
<li class=""><strong>Audit logs</strong>: Every logged IP is fake</li>
<li class=""><strong>Geo-IP</strong>: Attackers appear to be from any country</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="real-world-configurations">Real-World Configurations<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#real-world-configurations" class="hash-link" aria-label="Direct link to Real-World Configurations" title="Direct link to Real-World Configurations" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="nginx-on-the-same-machine">Nginx on the Same Machine<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#nginx-on-the-same-machine" class="hash-link" aria-label="Direct link to Nginx on the Same Machine" title="Direct link to Nginx on the Same Machine" translate="no">​</a></h3>
<p>The simplest case: Nginx and Fiber on the same server.</p>
<p><strong>Nginx config:</strong></p>
<div class="language-nginx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-nginx codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">server {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    listen 443 ssl;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    http2 on;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    server_name example.com;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    location / {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        proxy_pass http://127.0.0.1:3000;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        proxy_http_version 1.1;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        proxy_set_header Connection "";</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        proxy_set_header Host $host;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        proxy_set_header X-Forwarded-Proto $scheme;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></code></pre></div></div>
<p><strong>Fiber config:</strong></p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ProxyHeader</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">HeaderXForwardedFor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Loopback</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="traefik-in-docker">Traefik in Docker<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#traefik-in-docker" class="hash-link" aria-label="Direct link to Traefik in Docker" title="Direct link to Traefik in Docker" translate="no">​</a></h3>
<p>Traefik typically runs in the same Docker network:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ProxyHeader</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">HeaderXForwardedFor</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Private</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Docker networks use private IPs</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cloudflare--nginx--fiber">Cloudflare → Nginx → Fiber<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#cloudflare--nginx--fiber" class="hash-link" aria-label="Direct link to Cloudflare → Nginx → Fiber" title="Direct link to Cloudflare → Nginx → Fiber" translate="no">​</a></h3>
<p>When you have multiple proxies in a chain, each one appends to <code>X-Forwarded-For</code>. The header might look like: <code>203.0.113.50, 198.51.100.178, 127.0.0.1</code>.</p>
<p>Fiber reads the rightmost untrusted IP. With <code>Loopback: true</code>, it skips <code>127.0.0.1</code> (Nginx) and returns the next one. But the Cloudflare IP (<code>198.51.100.178</code>) needs to be trusted too.</p>
<p>For Cloudflare, use <code>CF-Connecting-IP</code> instead  -  it is always the real client IP regardless of proxy chain:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ProxyHeader</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"CF-Connecting-IP"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Loopback</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="detecting-https-behind-a-proxy">Detecting HTTPS Behind a Proxy<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#detecting-https-behind-a-proxy" class="hash-link" aria-label="Direct link to Detecting HTTPS Behind a Proxy" title="Direct link to Detecting HTTPS Behind a Proxy" translate="no">​</a></h2>
<p>When Nginx terminates TLS, Fiber's connection is plain HTTP. <code>c.Protocol()</code> returns <code>"http"</code> even though the client used HTTPS. This breaks CSRF (which checks the Referer scheme) and redirect logic.</p>
<p>The fix is the <code>X-Forwarded-Proto</code> header. Nginx sets it (see the config above), and Fiber reads it automatically when <code>TrustProxy</code> is enabled. No additional configuration needed  -  <code>c.Protocol()</code> will return <code>"https"</code> when the proxy says so.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-debug-endpoint">A Debug Endpoint<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#a-debug-endpoint" class="hash-link" aria-label="Direct link to A Debug Endpoint" title="Direct link to A Debug Endpoint" translate="no">​</a></h2>
<p>When setting up, add a temporary debug endpoint to verify everything works:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/debug/proxy"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"c.IP()"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">           c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IP</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"c.IPs()"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">          c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IPs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"c.Protocol()"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Protocol</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"IsProxyTrusted"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">   c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IsProxyTrusted</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"X-Forwarded-For"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-Forwarded-For"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"X-Forwarded-Proto"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-Forwarded-Proto"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Hit this endpoint and verify that <code>c.IP()</code> shows the real client IP and <code>c.Protocol()</code> shows <code>https</code>. Remove the endpoint before deploying to production.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-reverse-proxy-config#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/guide/reverse-proxy">Reverse Proxy Guide</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/api/app">App Configuration</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/api/ctx#ip">Ctx IP Method</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>reverse-proxy</category>
            <category>nginx</category>
            <category>traefik</category>
            <category>deployment</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Security Middleware Stack]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack</guid>
            <pubDate>Sat, 02 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Helmet + CORS + CSRF: the security stack nobody gets right on the first try  -  and the default settings that leave you exposed.]]></description>
            <content:encoded><![CDATA[<p>You add <code>helmet.New()</code>, <code>cors.New()</code>, and <code>csrf.New()</code> to your Fiber app. Three lines of code, three middleware, done. Your app is secure.</p>
<p>Except it is not. The default Helmet config does not set HSTS. The default CORS config allows every origin. The default CSRF config uses insecure cookies. And the order you register them in? That matters more than you think.</p>
<p>Most Fiber applications in production run with at least one of these misconfigured. Here is how to set them up so they actually protect your users.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-order-matters">Why Order Matters<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#why-order-matters" class="hash-link" aria-label="Direct link to Why Order Matters" title="Direct link to Why Order Matters" translate="no">​</a></h2>
<p>Middleware in Fiber executes in registration order. For security middleware, this creates dependencies:</p>
<ol>
<li class=""><strong>Helmet</strong> should come first  -  it sets response headers on every request regardless of outcome.</li>
<li class=""><strong>CORS</strong> should come next  -  it handles preflight OPTIONS requests and may short-circuit before your routes run.</li>
<li class=""><strong>CSRF</strong> should come after CORS  -  it needs the Origin header that CORS validates, and it should not interfere with preflight requests.</li>
</ol>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 1. Security headers on every response</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Config below</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 2. CORS for cross-origin access</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Config below</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 3. CSRF protection for state-changing requests</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Config below</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>If you put CSRF before CORS, preflight OPTIONS requests will fail CSRF validation and your frontend will get 403 errors before the actual request is even sent.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="helmet-the-defaults-that-leave-gaps">Helmet: The Defaults That Leave Gaps<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#helmet-the-defaults-that-leave-gaps" class="hash-link" aria-label="Direct link to Helmet: The Defaults That Leave Gaps" title="Direct link to Helmet: The Defaults That Leave Gaps" translate="no">​</a></h2>
<p>Helmet adds security headers to every response. The default configuration is reasonable, but it misses two critical settings for production.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="missing-hsts">Missing: HSTS<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#missing-hsts" class="hash-link" aria-label="Direct link to Missing: HSTS" title="Direct link to Missing: HSTS" translate="no">​</a></h3>
<p>HTTP Strict Transport Security tells browsers to always use HTTPS. The default <code>HSTSMaxAge</code> is <code>0</code>, which means the header is not sent at all:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    HSTSMaxAge</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">         </span><span class="token number" style="color:#36acaa">63072000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 2 years in seconds</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    HSTSPreloadEnabled</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// include subdomains by default (HSTSExcludeSubdomains is false)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Without HSTS, a user who types <code>http://yoursite.com</code> makes an unencrypted request before the redirect to HTTPS. An attacker on the same network can intercept that request.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="missing-content-security-policy">Missing: Content Security Policy<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#missing-content-security-policy" class="hash-link" aria-label="Direct link to Missing: Content Security Policy" title="Direct link to Missing: Content Security Policy" translate="no">​</a></h3>
<p>The default <code>ContentSecurityPolicy</code> is an empty string  -  no CSP header is sent. CSP is your primary defense against XSS:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    HSTSMaxAge</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">            </span><span class="token number" style="color:#36acaa">63072000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    HSTSPreloadEnabled</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ContentSecurityPolicy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Start strict and loosen as needed. <code>default-src 'self'</code> blocks everything from external sources by default. You add exceptions for what your app actually needs.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-you-get-for-free">What You Get for Free<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#what-you-get-for-free" class="hash-link" aria-label="Direct link to What You Get for Free" title="Direct link to What You Get for Free" translate="no">​</a></h3>
<p>The defaults do include useful protections:</p>
<ul>
<li class=""><code>X-Content-Type-Options: nosniff</code>  -  prevents MIME sniffing</li>
<li class=""><code>X-Frame-Options: SAMEORIGIN</code>  -  blocks clickjacking</li>
<li class=""><code>Referrer-Policy: no-referrer</code>  -  prevents leaking URLs to third parties</li>
<li class=""><code>Cross-Origin-Embedder-Policy: require-corp</code>  -  isolates your origin</li>
<li class=""><code>X-DNS-Prefetch-Control: off</code>  -  prevents DNS prefetching leaks</li>
</ul>
<p>These are solid defaults. Do not change them unless you have a specific reason.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cors-the-wildcard-trap">CORS: The Wildcard Trap<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#cors-the-wildcard-trap" class="hash-link" aria-label="Direct link to CORS: The Wildcard Trap" title="Direct link to CORS: The Wildcard Trap" translate="no">​</a></h2>
<p>The default CORS configuration allows all origins with <code>AllowOrigins: []string{"*"}</code>. For a public API with no authentication, that might be fine. For anything with cookies, sessions, or tokens, it is a security hole.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="for-an-api-with-authentication">For an API with Authentication<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#for-an-api-with-authentication" class="hash-link" aria-label="Direct link to For an API with Authentication" title="Direct link to For an API with Authentication" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AllowOrigins</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"https://app.example.com"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"https://admin.example.com"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AllowMethods</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"POST"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"PUT"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"DELETE"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AllowHeaders</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"Origin"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Content-Type"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Accept"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Authorization"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"X-Csrf-Token"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AllowCredentials</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    MaxAge</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">           </span><span class="token number" style="color:#36acaa">3600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Key points:</p>
<ul>
<li class=""><strong>AllowOrigins</strong> lists the exact domains that need access. No wildcards when using credentials.</li>
<li class=""><strong>AllowHeaders</strong> must include <code>X-Csrf-Token</code> if you are using CSRF with header extraction.</li>
<li class=""><strong>AllowCredentials</strong> is <code>true</code> because your frontend sends cookies.</li>
<li class=""><strong>MaxAge</strong> is <code>3600</code> (1 hour) so browsers cache preflight results instead of making an OPTIONS request before every POST.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-wildcard--credentials-panic">The Wildcard + Credentials Panic<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#the-wildcard--credentials-panic" class="hash-link" aria-label="Direct link to The Wildcard + Credentials Panic" title="Direct link to The Wildcard + Credentials Panic" translate="no">​</a></h3>
<p>If you try to set <code>AllowOrigins: []string{"*"}</code> with <code>AllowCredentials: true</code>, Fiber will panic at startup. This is intentional  -  the combination would let any website make authenticated requests to your API.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="subdomain-patterns">Subdomain Patterns<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#subdomain-patterns" class="hash-link" aria-label="Direct link to Subdomain Patterns" title="Direct link to Subdomain Patterns" translate="no">​</a></h3>
<p>For apps with multiple subdomains:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">AllowOrigins</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"https://*.example.com"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<p>This matches <code>app.example.com</code>, <code>admin.example.com</code>, and even <code>deep.nested.example.com</code>. Use this when you control the parent domain.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="csrf-the-cookie-nobody-configures">CSRF: The Cookie Nobody Configures<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#csrf-the-cookie-nobody-configures" class="hash-link" aria-label="Direct link to CSRF: The Cookie Nobody Configures" title="Direct link to CSRF: The Cookie Nobody Configures" translate="no">​</a></h2>
<p>The default CSRF configuration works for development but is insecure in production. The cookie is not marked as secure, not scoped to HTTPS, and uses a generic name.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="production-configuration-for-spas">Production Configuration for SPAs<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#production-configuration-for-spas" class="hash-link" aria-label="Direct link to Production Configuration for SPAs" title="Direct link to Production Configuration for SPAs" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token string" style="color:#e3116c">"__Host-csrf_"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSecure</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieHTTPOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// SPAs need JavaScript access</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSameSite</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Lax"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSessionOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">         extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-Csrf-Token"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Why these settings:</p>
<ul>
<li class=""><strong><code>__Host-</code> prefix</strong>: Browsers enforce that <code>__Host-</code> cookies are secure, have no domain, and have a path of <code>/</code>. This prevents cookie injection attacks.</li>
<li class=""><strong><code>CookieSecure: true</code></strong>: The cookie is only sent over HTTPS.</li>
<li class=""><strong><code>CookieHTTPOnly: false</code></strong>: Your JavaScript needs to read the cookie to send the token in a header. This is the necessary trade-off for SPAs.</li>
<li class=""><strong><code>CookieSameSite: "Lax"</code></strong>: The cookie is sent with top-level navigations but not with cross-site requests. This is the baseline CSRF protection.</li>
<li class=""><strong>Extractor from header</strong>: The CSRF token comes from the <code>X-Csrf-Token</code> header, not from the cookie itself. This is the Double Submit Cookie pattern.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="production-configuration-for-server-rendered-apps">Production Configuration for Server-Rendered Apps<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#production-configuration-for-server-rendered-apps" class="hash-link" aria-label="Direct link to Production Configuration for Server-Rendered Apps" title="Direct link to Production Configuration for Server-Rendered Apps" translate="no">​</a></h3>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token string" style="color:#e3116c">"__Host-csrf_"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSecure</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieHTTPOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// No JavaScript access needed</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSameSite</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Lax"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSessionOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">         extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromForm</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"_csrf"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Session</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">           sessionStore</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// More secure with sessions</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>For server-rendered apps, the token goes in a hidden form field, so <code>CookieHTTPOnly: true</code> is correct  -  JavaScript should not need the token.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-complete-stack">The Complete Stack<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#the-complete-stack" class="hash-link" aria-label="Direct link to The Complete Stack" title="Direct link to The Complete Stack" translate="no">​</a></h2>
<p>Here is the full security middleware stack for a typical SPA backend:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3/extractors"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3/middleware/cors"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3/middleware/csrf"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3/middleware/helmet"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Security headers</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helmet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    HSTSMaxAge</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">            </span><span class="token number" style="color:#36acaa">63072000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    HSTSPreloadEnabled</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ContentSecurityPolicy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// CORS</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AllowOrigins</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"https://app.example.com"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AllowMethods</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"POST"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"PUT"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"DELETE"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AllowHeaders</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"Origin"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Content-Type"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Accept"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Authorization"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"X-Csrf-Token"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AllowCredentials</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    MaxAge</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">           </span><span class="token number" style="color:#36acaa">3600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// CSRF</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token string" style="color:#e3116c">"__Host-csrf_"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSecure</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieHTTPOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSameSite</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Lax"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CookieSessionOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">         extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-Csrf-Token"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-checklist">The Checklist<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#the-checklist" class="hash-link" aria-label="Direct link to The Checklist" title="Direct link to The Checklist" translate="no">​</a></h2>
<p>Before deploying, verify:</p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Helmet HSTS is set with a max-age of at least 6 months</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Helmet CSP is set and tested with your frontend</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->CORS AllowOrigins lists specific domains, not <code>"*"</code></li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->CORS AllowHeaders includes <code>X-Csrf-Token</code></li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->CSRF cookie uses the <code>__Host-</code> prefix</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->CSRF CookieSecure is <code>true</code></li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->CSRF extraction is from header or form, never from cookie</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Middleware order is Helmet → CORS → CSRF</li>
</ul>
<p>Getting one of these wrong is common. Getting all of them right is what makes the difference.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-security-middleware-stack#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/helmet">Helmet Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/cors">CORS Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/csrf">CSRF Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/guide/extractors">Extractors Guide</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>security</category>
            <category>helmet</category>
            <category>cors</category>
            <category>csrf</category>
            <category>middleware</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Graceful Shutdown]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown</guid>
            <pubDate>Fri, 01 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why os.Exit kills your users' requests  -  and how to shut down Fiber v3 without dropping in-flight connections.]]></description>
            <content:encoded><![CDATA[<p>Every Go tutorial ends the same way: <code>log.Fatal(app.Listen(":3000"))</code>. The server starts, the tutorial is done. Nobody talks about what happens when the server stops.</p>
<p>Here is what happens: a deploy rolls out, the process gets SIGTERM, and every request that was mid-flight  -  a database write, a file upload, a payment confirmation  -  gets killed instantly. The client sees a connection reset. The database row is half-written. The payment went through but the confirmation never reached the user.</p>
<p>Graceful shutdown is not a nice-to-have. It is the difference between "the deploy went fine" and "we lost three transactions during the rollout."</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-happens-without-graceful-shutdown">What Happens Without Graceful Shutdown<a href="https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown#what-happens-without-graceful-shutdown" class="hash-link" aria-label="Direct link to What Happens Without Graceful Shutdown" title="Direct link to What Happens Without Graceful Shutdown" translate="no">​</a></h2>
<p>When Go's <code>http.Server</code> (or Fiber's <code>app.Listen</code>) receives a SIGTERM, the default behavior is to exit immediately. Every open connection is terminated. Every handler that was mid-execution gets no chance to finish.</p>
<p>The failure modes are predictable:</p>
<ul>
<li class=""><strong>Database writes</strong>: A multi-step insert completes partially. Your data is inconsistent.</li>
<li class=""><strong>External API calls</strong>: You called a payment provider, the charge went through, but your response handler never ran. The user sees an error but was actually charged.</li>
<li class=""><strong>File uploads</strong>: The upload was 90% complete. The file is corrupted on disk.</li>
</ul>
<p>These are not edge cases. They happen on every deploy if you are not handling shutdown properly.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fibers-shutdown-method">Fiber's Shutdown Method<a href="https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown#fibers-shutdown-method" class="hash-link" aria-label="Direct link to Fiber's Shutdown Method" title="Direct link to Fiber's Shutdown Method" translate="no">​</a></h2>
<p>Fiber v3 provides <code>app.Shutdown()</code>, which stops accepting new connections and waits for existing requests to complete:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">package</span><span class="token plain"> main</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"log"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"os"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"os/signal"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"syscall"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello, World!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Start server in a goroutine</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">go</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Listen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">":3000"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Server error: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Wait for interrupt signal</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    quit </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">chan</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Signal</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    signal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Notify</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">quit</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGINT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGTERM</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">quit</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Shutting down server..."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Shutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Fatalf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Server shutdown failed: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Server stopped gracefully"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p><code>app.Shutdown()</code> does two things: it stops the listener so no new connections arrive, and it waits for all active connections to finish. This is the minimum viable graceful shutdown.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-hooks-for-cleanup">Using Hooks for Cleanup<a href="https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown#using-hooks-for-cleanup" class="hash-link" aria-label="Direct link to Using Hooks for Cleanup" title="Direct link to Using Hooks for Cleanup" translate="no">​</a></h2>
<p>Fiber v3 has lifecycle hooks that let you run code during shutdown. The old <code>OnShutdown</code> from v2 has been replaced by two explicit hooks: <code>OnPreShutdown</code> runs before the server stops, and <code>OnPostShutdown</code> runs after it has fully stopped:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnPreShutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Deregistering from service discovery..."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> consul</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Agent</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ServiceDeregister</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">serviceID</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Failed to deregister: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnPostShutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Closing database connections..."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    db</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Close</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Flushing metrics buffer..."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    metricsClient</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Flush</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Use <code>OnPreShutdown</code> for tasks that should happen before the server stops accepting connections - like deregistering from service discovery so the load balancer stops routing traffic. Use <code>OnPostShutdown</code> for cleanup after the server has fully stopped - closing database pools, flushing log buffers, releasing resources.</p>
<p>Hooks execute in registration order. If you register multiple hooks of the same type, they run sequentially.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="adding-a-shutdown-timeout">Adding a Shutdown Timeout<a href="https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown#adding-a-shutdown-timeout" class="hash-link" aria-label="Direct link to Adding a Shutdown Timeout" title="Direct link to Adding a Shutdown Timeout" translate="no">​</a></h2>
<p>Waiting forever is not practical. A handler with a bug might never return. Add a timeout with <code>context.WithTimeout</code>:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">quit </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">chan</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Signal</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">signal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Notify</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">quit</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGINT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGTERM</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">quit</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Shutting down..."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Give active requests 10 seconds to finish</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cancel </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WithTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Background</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Second</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">defer</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">cancel</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">done </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">chan</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">go</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    done </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Shutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">select</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">done</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Shutdown error: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Shutdown complete"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Shutdown timed out, forcing exit"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The timeout should be shorter than your orchestrator's kill timeout. Kubernetes sends SIGTERM and waits 30 seconds by default before sending SIGKILL. So your shutdown timeout should be around 25 seconds  -  enough to drain, but with margin before the hard kill.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-health-check-connection">The Health Check Connection<a href="https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown#the-health-check-connection" class="hash-link" aria-label="Direct link to The Health Check Connection" title="Direct link to The Health Check Connection" translate="no">​</a></h2>
<p>If you are running behind a load balancer or in Kubernetes, your health check endpoint should reflect the shutdown state. Once you receive the shutdown signal, the readiness probe should start returning unhealthy so the load balancer stops sending new traffic:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> isShuttingDown atomic</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Bool</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/readyz"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> isShuttingDown</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Load</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusServiceUnavailable</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusOK</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// In shutdown handler:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">quit </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">chan</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Signal</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">signal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Notify</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">quit</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGINT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGTERM</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">quit</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">isShuttingDown</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Store</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Give load balancer time to notice the health check failure</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sleep</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Second</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Shutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>That <code>time.Sleep</code> before shutdown is not a mistake. It gives the load balancer time to mark your instance as unhealthy and stop routing traffic. Without it, you might stop accepting connections while the load balancer still thinks you are healthy, causing connection errors for clients.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-complete-pattern">The Complete Pattern<a href="https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown#the-complete-pattern" class="hash-link" aria-label="Direct link to The Complete Pattern" title="Direct link to The Complete Pattern" translate="no">​</a></h2>
<p>Putting it all together:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> isShuttingDown atomic</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Bool</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Routes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/readyz"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> isShuttingDown</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Load</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusServiceUnavailable</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusOK</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Cleanup hooks (OnPostShutdown runs after the server has stopped)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnPostShutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        db</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Close</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Start</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">go</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Listen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">":3000"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Listen error: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Wait for signal</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    quit </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">chan</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Signal</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    signal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Notify</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">quit</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGINT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGTERM</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">quit</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Begin graceful shutdown</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    isShuttingDown</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Store</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sleep</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Second</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Let LB drain</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cancel </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WithTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Background</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">25</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Second</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">defer</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">cancel</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    done </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">chan</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">go</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> done </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Shutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">select</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">done</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Shutdown complete"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Done</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Shutdown timed out"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-mistake-everyone-makes">The Mistake Everyone Makes<a href="https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown#the-mistake-everyone-makes" class="hash-link" aria-label="Direct link to The Mistake Everyone Makes" title="Direct link to The Mistake Everyone Makes" translate="no">​</a></h2>
<p>The most common mistake is calling <code>app.Shutdown()</code> in a <code>defer</code> inside <code>main</code>. The problem: <code>log.Fatal</code> calls <code>os.Exit</code>, which does not run deferred functions. If your <code>app.Listen</code> is wrapped in <code>log.Fatal</code>  -  like every tutorial shows  -  the shutdown code never runs.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// This does NOT work</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">defer</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Shutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Never executes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Fatal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Listen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">":3000"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// os.Exit skips defers</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Use the signal-based pattern shown above instead.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-graceful-shutdown#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/api/fiber#server-shutdown">App Shutdown Method</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/api/hooks">Hooks</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/healthcheck">Health Check Middleware</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>shutdown</category>
            <category>production</category>
            <category>operations</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Express-Style Handlers in Go: Fiber's Adapter That Nobody Expected]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-express-style-handlers</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-express-style-handlers</guid>
            <pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Fiber v3 accepts seventeen different handler signatures including Express-style, net/http, and fasthttp  -  here is when and why to use each.]]></description>
            <content:encoded><![CDATA[<p>If you have ever tried to migrate a project from Express.js to Go, you know the friction. It is not the language syntax or the type system. It is that every HTTP handler follows a completely different convention. Express gives you <code>(req, res, next)</code>. Go's standard library gives you <code>(w, r)</code>. Fiber gives you <code>(c) error</code>. The logic is the same, but the shape is different, and reshaping hundreds of handlers is tedious, error-prone work.</p>
<p>Fiber v3 decided to stop pretending this is not a problem. Its handler adapter accepts seventeen different function signatures  -  from Fiber-native to Express-style callbacks to raw <code>net/http</code> and <code>fasthttp</code> handlers. You can mix them in the same application without manual wrapping.</p>
<p>This sounds like magic. It is actually a carefully designed type switch in <code>adapter.go</code> that performs this adaptation at runtime when routes are registered, instead of forcing you to do it by hand.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-fiber-native-way">The Fiber-Native Way<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#the-fiber-native-way" class="hash-link" aria-label="Direct link to The Fiber-Native Way" title="Direct link to The Fiber-Native Way" translate="no">​</a></h2>
<p>The canonical Fiber handler is a function that takes a context and returns an error:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is case 1 in the adapter. If you are writing a new Fiber application from scratch, this is the only handler shape you need to know. The error return is important  -  it flows to the central error handler, which means error handling is consistent across your entire application.</p>
<p>Case 2 is the error-less variant:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Fiber runs the function and treats it as if it returned <code>nil</code>. This is convenient for handlers that cannot fail, like health checks, but you lose the ability to propagate errors. Use it sparingly.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="express-style-handlers-the-migration-bridge">Express-Style Handlers: The Migration Bridge<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#express-style-handlers-the-migration-bridge" class="hash-link" aria-label="Direct link to Express-Style Handlers: The Migration Bridge" title="Direct link to Express-Style Handlers: The Migration Bridge" translate="no">​</a></h2>
<p>This is where it gets interesting. Fiber v3 accepts handlers with <code>(req, res)</code> and <code>(req, res, next)</code> signatures that mirror Express.js patterns:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Like Express: app.get('/', (req, res) =&gt; { ... })</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello from Express-style"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The <code>fiber.Req</code> and <code>fiber.Res</code> types are views into the same underlying context, split into request and response concerns. This separation is natural for developers coming from Express, where <code>req</code> and <code>res</code> are distinct objects.</p>
<p>The middleware pattern translates directly too:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Like Express: app.use((req, res, next) =&gt; { ... })</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    start </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"%s took %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Since</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">start</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>There are ten Express-style variants (cases 3 through 12), covering every combination of:</p>
<ul>
<li class="">With or without <code>next</code> callback</li>
<li class=""><code>next</code> that takes no arguments, <code>next(error)</code>, or <code>next(error) error</code></li>
<li class="">Handler with or without error return</li>
</ul>
<p>This means you can translate most Express middleware patterns directly without redesigning the error flow.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="error-propagation-in-next-callbacks">Error Propagation in Next Callbacks<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#error-propagation-in-next-callbacks" class="hash-link" aria-label="Direct link to Error Propagation in Next Callbacks" title="Direct link to Error Propagation in Next Callbacks" translate="no">​</a></h2>
<p>The different <code>next</code> signatures handle errors differently, and understanding this matters for middleware:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// next() error  -  call next, get the downstream error back</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"downstream error: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// next(error)  -  pass an error to short-circuit the chain</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token function" style="color:#d73a49">isAuthorized</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ErrUnauthorized</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// continue the chain</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// next(error) error  -  both send and receive errors</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Post-processing after downstream error</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">500</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"something went wrong"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>If your handler returns an error <em>and</em> the next callback recorded an error, Fiber prioritizes the handler's return value. This prevents confusing situations where a downstream error silently overrides a handler's explicit response.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="reusing-nethttp-handlers">Reusing net/http Handlers<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#reusing-nethttp-handlers" class="hash-link" aria-label="Direct link to Reusing net/http Handlers" title="Direct link to Reusing net/http Handlers" translate="no">​</a></h2>
<p>Go's standard library ecosystem is enormous. There are handlers for Prometheus metrics, pprof profiling, OAuth callbacks, and hundreds of other things that accept <code>http.ResponseWriter</code> and <code>*http.Request</code>. Fiber can mount them directly:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"net/http"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// http.HandlerFunc works directly</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/metrics"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">HandlerFunc</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">metricsHandler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// http.Handler interface works too</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/debug/*"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pprofMux</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Raw function signature</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/legacy"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">w http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ResponseWriter</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusOK</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Write</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token function" style="color:#d73a49">byte</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"from net/http"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>There is an important caveat: these handlers go through <code>fasthttpadaptor</code>, which adds overhead compared to native Fiber handlers. More importantly, they do not receive <code>fiber.Ctx</code>, so they cannot call <code>c.Next()</code> and always terminate the handler chain. They are meant for leaf handlers, not middleware.</p>
<p>If you need a <code>net/http</code> middleware to participate in the Fiber chain, use the <a class="" href="https://docs.gofiber.io/middleware/adaptor">Adaptor middleware</a> instead, which provides full bidirectional conversion.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="mounting-fasthttp-handlers">Mounting fasthttp Handlers<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#mounting-fasthttp-handlers" class="hash-link" aria-label="Direct link to Mounting fasthttp Handlers" title="Direct link to Mounting fasthttp Handlers" translate="no">​</a></h2>
<p>Since Fiber runs on fasthttp internally, fasthttp handlers integrate with zero overhead:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/valyala/fasthttp"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/fast"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fasthttp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">RequestCtx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ctx</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SetStatusCode</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ctx</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SetBody</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token function" style="color:#d73a49">byte</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"zero overhead"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// With error return</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/fast-err"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fasthttp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">RequestCtx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> ctx</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">QueryArgs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Peek</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fail"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"intentional failure"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ctx</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SetStatusCode</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is useful when you have existing fasthttp code that you are migrating into a Fiber application, or when you need direct access to fasthttp features that Fiber does not expose.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-real-migration-express-to-fiber">A Real Migration: Express to Fiber<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#a-real-migration-express-to-fiber" class="hash-link" aria-label="Direct link to A Real Migration: Express to Fiber" title="Direct link to A Real Migration: Express to Fiber" translate="no">​</a></h2>
<p>Suppose you have an Express.js application with middleware like this:</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Express.js</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">req</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> res</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> next</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> start </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Date</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'finish'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">req</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">method</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c"> </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">req</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">path</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c"> - </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation known-class-name class-name">Date</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation method function property-access" style="color:#d73a49">now</span><span class="token template-string interpolation punctuation" style="color:#393A34">(</span><span class="token template-string interpolation punctuation" style="color:#393A34">)</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#393A34">-</span><span class="token template-string interpolation"> start</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c">ms</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'/users/:id'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">req</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> res</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">findUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">params</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">404</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">json</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">error</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'not found'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">json</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>The Fiber v3 equivalent, using Express-style handlers, looks like this:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Fiber v3 with Express-style handlers</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    start </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"%s %s - %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Method</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Since</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">start</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users/:id"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    user </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">findUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Params</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> user </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">404</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"error"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"not found"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The structure is nearly identical. The shapes match. A developer who knows Express can read this code and understand what it does without learning Fiber's conventions first. Over time, as the team gets comfortable, they can gradually migrate to idiomatic <code>fiber.Ctx</code> handlers  -  or not, if the Express style works for them.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-to-use-which">When to Use Which<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#when-to-use-which" class="hash-link" aria-label="Direct link to When to Use Which" title="Direct link to When to Use Which" translate="no">​</a></h2>
<p><strong>Use <code>func(fiber.Ctx) error</code></strong> for new code. It is the most idiomatic, has the best tooling support, and gives you full access to Fiber's context API.</p>
<p><strong>Use Express-style <code>(req, res)</code> handlers</strong> when migrating from Express.js or when your team thinks in terms of separate request and response objects. There is no performance penalty  -  the adapter resolves at application startup.</p>
<p><strong>Use <code>net/http</code> handlers</strong> to mount existing Go ecosystem tools (Prometheus, pprof, OAuth libraries) without writing adapter code. Accept the overhead trade-off for leaf handlers.</p>
<p><strong>Use <code>fasthttp</code> handlers</strong> for existing fasthttp code or when you need direct access to the underlying request context. This is an escape hatch, not a primary pattern.</p>
<p><strong>Avoid mixing styles within the same route group.</strong> If your <code>/api/v1</code> group uses Fiber-native handlers, do not introduce Express-style handlers in the same group. Consistency within a module matters more than using the "best" handler type everywhere.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If you are starting a new project, use Fiber-native handlers exclusively. There is no reason to use the adapter when you have no legacy code.</p>
<p>If you are migrating from Express, start by converting your route definitions and middleware using Express-style handlers. Get the application working first, then convert to idiomatic Fiber handlers one module at a time during regular refactoring.</p>
<p>If you are integrating Go ecosystem tools, mount them directly and move on. The adapter handles the complexity.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/api/app#route-handlers">App Route Handlers</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/adaptor">Adaptor Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>handlers</category>
            <category>express</category>
            <category>adapter</category>
            <category>migration</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[From fmt.Println to Production Logging in Fiber v3]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-structured-logging</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-structured-logging</guid>
            <pubDate>Wed, 15 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Move beyond basic request logging to structured, queryable, production-grade observability with Fiber v3's Logger middleware.]]></description>
            <content:encoded><![CDATA[<p>There is a moment in every project's life where someone greps the production logs for a bug report and realizes that <code>fmt.Println("got here")</code> is the only evidence of what happened. The request came in, something went wrong, and the logs show a status code with no context about which user, which endpoint, or which upstream service was involved.</p>
<p>Logging sounds boring until it is 2 AM and your only debugging tool is <code>kubectl logs</code>. At that point, the difference between a flat text line and a structured JSON object with a request ID, latency, and user context is the difference between finding the bug in five minutes and finding it in two hours.</p>
<p>Fiber v3's Logger middleware is designed to bridge that gap without requiring you to rewrite your application.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-default-good-enough-to-start">The Default: Good Enough to Start<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#the-default-good-enough-to-start" class="hash-link" aria-label="Direct link to The Default: Good Enough to Start" title="Direct link to The Default: Good Enough to Start" translate="no">​</a></h2>
<p>Out of the box, the Logger middleware gives you a single line per request with the most useful fields:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Output: [15:04:05] 127.0.0.1 200 - 1.234ms GET /api/users</span><br></div></code></pre></div></div>
<p>That is timestamp, IP, status code, latency, method, and path. For local development and small services, this is fine. Register it early  -  routes added after the logger are logged, routes added before it are not.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// register first</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> handler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// this route will be logged</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="structured-json-logging">Structured JSON Logging<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#structured-json-logging" class="hash-link" aria-label="Direct link to Structured JSON Logging" title="Direct link to Structured JSON Logging" translate="no">​</a></h2>
<p>The moment your logs go to an aggregation system  -  Elasticsearch, Loki, CloudWatch, Datadog  -  you need structured output. Flat text requires fragile regex to query. JSON is queryable by default.</p>
<p>Fiber provides a built-in JSON format:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Format</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">JSONFormat</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This produces JSON-like structured output. Note that <code>logger.JSONFormat</code> uses a predefined format string where keys are not quoted - the output is not strict JSON. If you need valid JSON for your log aggregator, use a custom format string with properly quoted keys or use a dedicated logging library like Zap or zerolog (covered later in this post).</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">{time: 15:04:05, ip: 127.0.0.1, method: GET, url: /api/users, status: 200, bytesSent: 1234}</span><br></div></code></pre></div></div>
<p>For teams using Elastic Common Schema, there is a dedicated ECS format:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Format</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ECSFormat</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This outputs logs that Elasticsearch, Kibana, and the Elastic APM can ingest without any parsing rules. The schema includes <code>@timestamp</code>, <code>ecs.version</code>, <code>client.ip</code>, <code>http.request.method</code>, and <code>http.response.status_code</code>  -  all in the right places.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="custom-formats-for-your-stack">Custom Formats for Your Stack<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#custom-formats-for-your-stack" class="hash-link" aria-label="Direct link to Custom Formats for Your Stack" title="Direct link to Custom Formats for Your Stack" translate="no">​</a></h2>
<p>The predefined formats cover common cases, but most teams need something specific. Fiber's format string uses <code>${tag}</code> placeholders that you can arrange freely:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Format</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"${time} | ${status} | ${latency} | ${ip} | ${method} | ${path} | ${error}\n"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TimeFormat</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"2006-01-02T15:04:05Z07:00"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TimeZone</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"UTC"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>For structured JSON with custom fields, build the JSON string manually:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Format</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`{"ts":"${time}","method":"${method}","path":"${path}",`</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        `</span><span class="token string" style="color:#e3116c">"status"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">$</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">status</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"latency"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token string" style="color:#e3116c">"${latency}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"ip"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token string" style="color:#e3116c">"${ip}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">` +</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        `</span><span class="token plain">"bytes_sent</span><span class="token string" style="color:#e3116c">":${bytesSent},"</span><span class="token plain">bytes_recv</span><span class="token string" style="color:#e3116c">":${bytesReceived}}` + "</span><span class="token plain">\n"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TimeFormat</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">RFC3339</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TimeZone</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">   </span><span class="token string" style="color:#e3116c">"UTC"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The available tags cover nearly everything you would want: <code>${pid}</code>, <code>${ip}</code>, <code>${ips}</code>, <code>${host}</code>, <code>${method}</code>, <code>${path}</code>, <code>${url}</code>, <code>${ua}</code>, <code>${latency}</code>, <code>${status}</code>, <code>${bytesSent}</code>, <code>${bytesReceived}</code>, <code>${route}</code>, <code>${error}</code>, <code>${body}</code>, <code>${resBody}</code>, <code>${reqHeaders}</code>, <code>${queryParams}</code>.</p>
<p>You can also reference specific headers, cookies, query params, and locals:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">Format</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`${reqHeader:X-Request-Id} ${cookie:session_id} ${query:page} ${locals:user_id}`</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"\n"</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="adding-request-ids">Adding Request IDs<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#adding-request-ids" class="hash-link" aria-label="Direct link to Adding Request IDs" title="Direct link to Adding Request IDs" translate="no">​</a></h2>
<p>The single most useful thing you can add to your logs is a request ID. It lets you correlate every log line, error, and downstream service call to a single request.</p>
<p>Combine the RequestID middleware with a custom logger tag:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">requestid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    CustomTags</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">map</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">LogFunc</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"request_id"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">output logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Buffer</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> data </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Data</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> output</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">requestid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Format</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`{"request_id":"${request_id}","method":"${method}","path":"${path}","status":${status}}`</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"\n"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Now every log line carries the request ID. When a user reports a problem, they send you the ID from the response header and you can trace everything that happened.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-done-callback-conditional-alerting">The Done Callback: Conditional Alerting<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#the-done-callback-conditional-alerting" class="hash-link" aria-label="Direct link to The Done Callback: Conditional Alerting" title="Direct link to The Done Callback: Conditional Alerting" translate="no">​</a></h2>
<p>The <code>Done</code> callback fires after each log line is written. This is useful for routing specific events to different systems without building a separate middleware:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TimeFormat</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">RFC3339Nano</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Done</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> logString </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">byte</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Response</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">StatusCode</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">500</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            alerting</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendToSlack</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logString</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is not a replacement for a proper alerting pipeline, but it is a pragmatic way to get notified about server errors immediately without deploying additional infrastructure.</p>
<p>You can also use it for audit logging  -  writing specific requests to a separate file or database:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">Done</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> logString </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">byte</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> strings</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">HasPrefix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/admin"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        auditLog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Write</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logString</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="skipping-noise">Skipping Noise<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#skipping-noise" class="hash-link" aria-label="Direct link to Skipping Noise" title="Direct link to Skipping Noise" translate="no">​</a></h2>
<p>Health check endpoints, metrics scraping, and Kubernetes probes generate enormous amounts of log traffic with zero diagnostic value. The <code>Skip</code> function lets you filter them out:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Skip</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">bool</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/healthz"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/readyz"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/metrics"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The difference between <code>Next</code> and <code>Skip</code> matters here. <code>Next</code> skips the middleware entirely  -  the request is not logged and no log processing happens. <code>Skip</code> still processes the request through the handler chain but suppresses the log output. For performance, prefer <code>Next</code> when you do not need any log processing for skipped routes.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="writing-to-files">Writing to Files<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#writing-to-files" class="hash-link" aria-label="Direct link to Writing to Files" title="Direct link to Writing to Files" translate="no">​</a></h2>
<p>For environments without a log aggregator, writing to files is still the right approach:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">f</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OpenFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./access.log"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">O_RDWR</span><span class="token operator" style="color:#393A34">|</span><span class="token plain">os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">O_CREATE</span><span class="token operator" style="color:#393A34">|</span><span class="token plain">os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">O_APPEND</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0666</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Fatal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">defer</span><span class="token plain"> f</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Close</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Stream</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        f</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    DisableColors</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// no ANSI in files</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The <code>DisableColors</code> flag is important. Without it, your log files fill up with ANSI escape codes that make them unreadable in plain text editors and break log parsing tools.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="integrating-with-zap-zerolog-and-friends">Integrating with Zap, Zerolog, and Friends<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#integrating-with-zap-zerolog-and-friends" class="hash-link" aria-label="Direct link to Integrating with Zap, Zerolog, and Friends" title="Direct link to Integrating with Zap, Zerolog, and Friends" translate="no">​</a></h2>
<p>Most Go teams already have a logging library. Fiber's <code>LoggerToWriter</code> adapter lets you pipe the logger middleware output into any logger that satisfies an interface:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    fiberzap </span><span class="token string" style="color:#e3116c">"github.com/gofiber/contrib/v3/zap"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3/log"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3/middleware/logger"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">zapLogger </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiberzap</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewLogger</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiberzap</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">LoggerConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ExtraKeys</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"request_id"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Stream</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">LoggerToWriter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">zapLogger</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">LevelDebug</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Note the import path: Fiber v3 contrib packages live under <code>github.com/gofiber/contrib/v3/</code> and drop the <code>fiber</code> prefix from their names. So <code>fiberzap/v2</code> becomes <code>contrib/v3/zap</code>, <code>fiberzerolog</code> becomes <code>contrib/v3/zerolog</code>, and so on.</p>
<p>This means Fiber's request logs go through your existing log pipeline, with your existing log levels, formatters, and sinks. You do not need to maintain two separate logging systems.</p>
<p>The same pattern works with <code>contrib/v3/zerolog</code> and any logger that implements Fiber's <code>AllLogger</code> interface.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="common-pitfalls">Common Pitfalls<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#common-pitfalls" class="hash-link" aria-label="Direct link to Common Pitfalls" title="Direct link to Common Pitfalls" translate="no">​</a></h2>
<p><strong>Logging request bodies in production.</strong> The <code>${body}</code> tag exists for debugging, but enabling it in production means every POST body  -  including passwords, tokens, and PII  -  ends up in your logs. Only use it in development or behind a feature flag.</p>
<p><strong>Logging response bodies.</strong> Same problem. The <code>${resBody}</code> tag is useful for debugging, but it can log sensitive data and dramatically increase log volume.</p>
<p><strong>Forgetting timezone.</strong> The default timezone is <code>"Local"</code>, which means your logs use whatever the server's timezone is. In a distributed system, different servers might log in different timezones. Always set <code>TimeZone: "UTC"</code> for production.</p>
<p><strong>Registration order.</strong> The logger only captures routes registered after it. If you register a health check route before the logger, it will not be logged  -  which might actually be what you want.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If you are using <code>fmt.Println</code> for debugging, switch to the Logger middleware with the default format. You get latency and status codes immediately, which eliminates the most common "what happened?" questions.</p>
<p>Next, switch to JSON format and add a request ID. This alone makes your logs queryable and correlatable, which is 80% of what you need for production debugging.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-structured-logging#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/logger">Logger Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/requestid">RequestID Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>logging</category>
            <category>observability</category>
            <category>middleware</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Testing Fiber Apps: The Patterns Nobody Talks About]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-testing-patterns</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-testing-patterns</guid>
            <pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Go beyond basic handler tests with patterns for middleware chains, error handlers, route groups, and integration testing in Fiber v3.]]></description>
            <content:encoded><![CDATA[<p>Every Fiber tutorial shows you how to test a single GET handler. Create an app, register a route, call <code>app.Test()</code>, check the status code. Done.</p>
<p>Then you try to test something real  -  a middleware chain where auth runs before validation, a custom error handler that renders different responses based on content type, a route group with shared state  -  and the tutorial patterns fall apart. The handler works in isolation but fails when composed. The test passes with a hardcoded body but breaks when you add a request ID middleware that changes the response shape.</p>
<p>Testing Fiber applications well requires patterns that match how Fiber applications actually work: as compositions of handlers, middleware, and configuration that interact in specific ways.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-basics-apptest">The Basics: app.Test()<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#the-basics-apptest" class="hash-link" aria-label="Direct link to The Basics: app.Test()" title="Direct link to The Basics: app.Test()" translate="no">​</a></h2>
<p>Fiber's <code>Test</code> method is the foundation. It takes a standard <code>*http.Request</code> and returns a standard <code>*http.Response</code>, no actual network listener required:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">TestGetUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users/:id"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Params</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MethodGet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/users/42"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        t</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Fatal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This works because Fiber internally creates a <code>fasthttp.RequestCtx</code> from your <code>http.Request</code>, runs the full router and middleware stack, and converts the result back. No port binding, no goroutine leaks, no flaky tests from port conflicts.</p>
<p>The default timeout is 1 second. For handlers that do real work, like database queries in integration tests, increase it:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TestConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Timeout</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Second</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>For unit tests where you know the handler returns immediately, disable the timeout entirely:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TestConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Timeout</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testing-middleware-in-isolation">Testing Middleware in Isolation<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#testing-middleware-in-isolation" class="hash-link" aria-label="Direct link to Testing Middleware in Isolation" title="Direct link to Testing Middleware in Isolation" translate="no">​</a></h2>
<p>A middleware function is just a handler that calls <code>c.Next()</code>. You can test it by creating a minimal app with the middleware and a dummy handler:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">TestAuthMiddleware</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">authMiddleware</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/protected"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"ok"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Without token  -  should get 401</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MethodGet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/protected"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">401</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// With valid token  -  should pass through</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MethodGet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/protected"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Authorization"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Bearer valid-token"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The important thing is that this tests the middleware in context  -  with a real router, real header parsing, and real <code>c.Next()</code> propagation. You are testing behavior, not implementation.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testing-middleware-composition">Testing Middleware Composition<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#testing-middleware-composition" class="hash-link" aria-label="Direct link to Testing Middleware Composition" title="Direct link to Testing Middleware Composition" translate="no">​</a></h2>
<p>The bugs that matter most happen between middleware, not inside them. When auth, rate limiting, and request ID middleware interact, the order and error propagation matter.</p>
<p>Test the composition explicitly:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">TestMiddlewareChain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">requestid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">authMiddleware</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">rateLimiter</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/api/data"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dataHandler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// An unauthenticated request should fail at auth,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// not at the rate limiter</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MethodGet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/api/data"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">401</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// The response should still have a request ID,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// because requestid runs before auth</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NotEmpty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-Request-Id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This catches the common bug where a middleware short-circuits and skips downstream middleware that should still run. Request ID middleware should always add a header, even on error responses. If your tests only check the happy path, you will never catch this.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testing-custom-error-handlers">Testing Custom Error Handlers<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#testing-custom-error-handlers" class="hash-link" aria-label="Direct link to Testing Custom Error Handlers" title="Direct link to Testing Custom Error Handlers" translate="no">​</a></h2>
<p>Custom error handlers are critical infrastructure, but they are rarely tested directly. Build a test that triggers different error types and verifies the response:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">TestCustomErrorHandler</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        ErrorHandler</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> myErrorHandler</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Route that returns a fiber.Error</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/not-found"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">404</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Page not found"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Route that returns an unexpected error</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/crash"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"database connection failed: host=db.internal"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Known error: should return the controlled message</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MethodGet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/not-found"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    body</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> io</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ReadAll</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">404</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Contains</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Page not found"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Unknown error: should NOT leak the internal message</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MethodGet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/crash"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    body</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> io</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ReadAll</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">500</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NotContains</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"database connection failed"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NotContains</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"db.internal"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>That last assertion  -  checking that the response does <em>not</em> contain the internal error  -  is the most important test in your entire error handling suite. It catches information leakage.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testing-route-groups">Testing Route Groups<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#testing-route-groups" class="hash-link" aria-label="Direct link to Testing Route Groups" title="Direct link to Testing Route Groups" translate="no">​</a></h2>
<p>When you have nested route groups with group-specific middleware, test them as a unit:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">setupAPIRoutes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">app </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    api </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Group</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/api"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">apiKeyAuth</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    v1 </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Group</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/v1"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    v1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> listUsers</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    v1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> createUser</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    v2 </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Group</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/v2"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    v2</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> listUsersV2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">TestAPIRouteGroup</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">setupAPIRoutes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    tests </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        name       </span><span class="token builtin">string</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        path       </span><span class="token builtin">string</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        method     </span><span class="token builtin">string</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        apiKey     </span><span class="token builtin">string</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        wantStatus </span><span class="token builtin">int</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"v1 without key"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/api/v1/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">401</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"v1 with key"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/api/v1/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"valid-key"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"v2 with key"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/api/v2/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"valid-key"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"no version"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/api/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"valid-key"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">404</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tt </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">range</span><span class="token plain"> tests </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        t</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            req </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">method</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">path</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> tt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">apiKey </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-API-Key"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">apiKey</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">wantStatus</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The key pattern is extracting route setup into a function that accepts <code>*fiber.App</code>. This lets your tests use the exact same setup as your production code without duplicating route definitions.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testing-json-request-bodies">Testing JSON Request Bodies<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#testing-json-request-bodies" class="hash-link" aria-label="Direct link to Testing JSON Request Bodies" title="Direct link to Testing JSON Request Bodies" translate="no">​</a></h2>
<p>POST and PUT handlers need request bodies. Use <code>strings.NewReader</code> or <code>bytes.NewBuffer</code>:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">TestCreateUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> createUserHandler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    body </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`{"name": "Alice", "email": "alice@example.com"}`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MethodPost</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        strings</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewReader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Content-Type"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"application/json"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">201</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> result </span><span class="token keyword" style="color:#00009f">map</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain">any</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    json</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewDecoder</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Decode</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Alice"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> result</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"name"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The <code>Content-Type</code> header matters. Without it, Fiber's body parser may not parse the JSON correctly.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testing-response-headers">Testing Response Headers<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#testing-response-headers" class="hash-link" aria-label="Direct link to Testing Response Headers" title="Direct link to Testing Response Headers" translate="no">​</a></h2>
<p>Rate limit headers, CORS headers, cache headers  -  these are part of your API contract. Test them explicitly:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">TestRateLimitHeaders</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"ok"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MethodGet</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"5"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-RateLimit-Limit"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    assert</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Equal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"4"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-RateLimit-Remaining"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-helper-that-pays-for-itself">A Helper That Pays for Itself<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#a-helper-that-pays-for-itself" class="hash-link" aria-label="Direct link to A Helper That Pays for Itself" title="Direct link to A Helper That Pays for Itself" translate="no">​</a></h2>
<p>If you find yourself writing the same <code>httptest.NewRequest</code> / <code>app.Test</code> / <code>io.ReadAll</code> sequence in every test, extract it once:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">testRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">testing</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> app </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> method</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> path </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> opts </span><span class="token operator" style="color:#393A34">...</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">*</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    t</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Helper</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    req </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> httptest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">method</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> path</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> opt </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">range</span><span class="token plain"> opts </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">opt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        t</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Fatal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">defer</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Body</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Close</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    body</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> io</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">ReadAll</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> resp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">string</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">body</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Usage:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">status</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> body </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">testRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/users/42"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Header</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Authorization"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Bearer token"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This keeps tests focused on what matters: the inputs, the expected status, and the expected body.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If your test suite only has happy-path tests, add error-path tests first. Test that unauthenticated requests get 401, that invalid input gets 422, and that internal errors return generic messages without leaking details.</p>
<p>Then test your middleware composition. Register the same middleware stack you use in production and verify that they interact correctly. These are the tests that catch the bugs you will actually ship.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-testing-patterns#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/api/app#test">App Test Method</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/guide/error-handling">Error Handling Guide</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>testing</category>
            <category>go</category>
            <category>patterns</category>
            <category>best-practices</category>
        </item>
        <item>
            <title><![CDATA[Rate Limiting: Protecting Your API Without Punishing Your Users]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide</guid>
            <pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Implement rate limiting in Fiber v3 that actually makes sense  -  dynamic limits, sliding windows, and per-endpoint strategies.]]></description>
            <content:encoded><![CDATA[<p>Rate limiting is one of those features that every production API needs, nobody enjoys implementing, and most teams get subtly wrong the first time.</p>
<p>The common mistake is not forgetting rate limiting entirely. It is applying a single global limit and calling it done. Fifty requests per minute, no exceptions, no differentiation. Your power users hit the wall during normal operations. Scrapers figure out the exact limit and stay just below it. Login endpoints get the same allowance as read-only data endpoints. Everyone is equally unhappy.</p>
<p>Fiber v3's Limiter middleware ships with the primitives to do better: dynamic limits per route, sliding window algorithms, per-user keys, and pluggable storage backends. The trick is knowing when to use which.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-five-minute-setup">The Five-Minute Setup<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#the-five-minute-setup" class="hash-link" aria-label="Direct link to The Five-Minute Setup" title="Direct link to The Five-Minute Setup" translate="no">​</a></h2>
<p>If you have never added rate limiting before, start here. This gets a basic limiter running with sane defaults:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3/middleware/limiter"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>That is it. You get 5 requests per minute per IP, a 429 response when the limit is exceeded, and standard <code>X-RateLimit-*</code> headers so clients can see their remaining quota. For a weekend project or an internal tool, this might be all you need.</p>
<p>But production APIs have different requirements.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fixed-window-vs-sliding-window">Fixed Window vs. Sliding Window<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#fixed-window-vs-sliding-window" class="hash-link" aria-label="Direct link to Fixed Window vs. Sliding Window" title="Direct link to Fixed Window vs. Sliding Window" translate="no">​</a></h2>
<p>The default algorithm is a fixed window: every 60 seconds the counter resets to zero. This works, but it has a well-known burst problem. If a client sends 5 requests at second 59 and 5 more at second 61, they have made 10 requests in 2 seconds despite a "5 per minute" limit. The window boundary creates a loophole.</p>
<p>The sliding window algorithm smooths this out by considering the previous window's traffic:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">               </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">30</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Second</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    LimiterMiddleware</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SlidingWindow</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The math is straightforward: it takes the number of requests from the previous window, weights them by how much of the current window has elapsed, and adds the current window's count. If the previous window had 15 requests and we are 40% into the current window, the effective count is <code>15 * 0.6 + currentCount</code>. This eliminates the boundary burst without adding meaningful overhead.</p>
<p>Use fixed windows for simple use cases where exact precision does not matter. Use sliding windows for auth endpoints, payment APIs, or anywhere burst protection matters.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dynamic-limits-not-all-endpoints-are-equal">Dynamic Limits: Not All Endpoints Are Equal<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#dynamic-limits-not-all-endpoints-are-equal" class="hash-link" aria-label="Direct link to Dynamic Limits: Not All Endpoints Are Equal" title="Direct link to Dynamic Limits: Not All Endpoints Are Equal" translate="no">​</a></h2>
<p>A login endpoint that accepts passwords should have a much tighter limit than a product catalog that serves public data. With <code>MaxFunc</code>, you can calculate limits per request:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    MaxFunc</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> strings</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">HasPrefix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/auth"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// strict: 5 per window for auth</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> strings</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">HasPrefix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/api/v1/search"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// generous: search is read-only</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">default</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// reasonable default</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>A more sophisticated approach uses the authenticated user's tier:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">MaxFunc</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    tier</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ok </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Locals</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"user_tier"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">ok </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// unauthenticated baseline</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">switch</span><span class="token plain"> tier </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"enterprise"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"pro"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">default</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">50</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<p>This requires your auth middleware to run before the limiter. Registration order matters  -  middleware executes in the order you call <code>app.Use</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dynamic-expiration-windows">Dynamic Expiration Windows<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#dynamic-expiration-windows" class="hash-link" aria-label="Direct link to Dynamic Expiration Windows" title="Direct link to Dynamic Expiration Windows" translate="no">​</a></h2>
<p>Similarly, <code>ExpirationFunc</code> lets you vary the time window per request. A login endpoint might use a longer window to prevent slow brute force attacks:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ExpirationFunc</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Duration </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/login"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/reset-password"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute </span><span class="token comment" style="color:#999988;font-style:italic">// 10 attempts per 5 minutes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute </span><span class="token comment" style="color:#999988;font-style:italic">// 10 per minute everywhere else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="better-key-generation">Better Key Generation<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#better-key-generation" class="hash-link" aria-label="Direct link to Better Key Generation" title="Direct link to Better Key Generation" translate="no">​</a></h2>
<p>The default key generator uses the client IP. Behind a load balancer or CDN, every request might appear to come from the same IP unless Fiber knows which proxy headers to trust.</p>
<p>The correct approach is to configure Fiber's built-in proxy trust settings so <code>c.IP()</code> resolves the real client IP safely:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">          </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">TrustProxyConfig</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Proxies</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"10.0.0.0/8"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"172.16.0.0/12"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ProxyHeader</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"X-Forwarded-For"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>With that in place, the default <code>KeyGenerator</code> using <code>c.IP()</code> already does the right thing. Do not parse <code>X-Forwarded-For</code> manually  -  clients can spoof that header to bypass IP-based limits unless your proxy overwrites it.</p>
<p>For authenticated APIs, a better key is the user ID. This means the limit follows the account, not the IP, which is the correct behavior for mobile users who switch networks:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">KeyGenerator</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> userID</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ok </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Locals</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"user_id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> ok </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"user:"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> userID</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ip:"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IP</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<p>The <code>user:</code> and <code>ip:</code> prefixes prevent collisions between user IDs and IP addresses.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="custom-limit-reached-responses">Custom Limit-Reached Responses<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#custom-limit-reached-responses" class="hash-link" aria-label="Direct link to Custom Limit-Reached Responses" title="Direct link to Custom Limit-Reached Responses" translate="no">​</a></h2>
<p>When a client hits the limit, the default handler returns a bare 429 status. API consumers deserve more:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">LimitReached</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    retryAfter </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">GetRespHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Retry-After"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusTooManyRequests</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"error"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">       </span><span class="token string" style="color:#e3116c">"rate_limit_exceeded"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"message"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"Too many requests. Please slow down."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"retry_after"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> retryAfter</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<p>This gives clients machine-readable information they can use to implement backoff correctly.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="skipping-certain-requests">Skipping Certain Requests<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#skipping-certain-requests" class="hash-link" aria-label="Direct link to Skipping Certain Requests" title="Direct link to Skipping Certain Requests" translate="no">​</a></h2>
<p>Not everything should count. Health check endpoints should never be rate limited  -  a monitoring system polling <code>/healthz</code> every second is expected behavior:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Next</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">bool</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Skip health checks and internal IPs</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/healthz"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/readyz"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IP</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"10.0.0.1"</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// internal monitoring</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>You can also skip failed requests so that server errors do not eat a user's quota:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">SkipFailedRequests</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// status &gt;= 400 won't count</span><br></div></code></pre></div></div>
<p>Or the opposite  -  only count failed requests to detect brute force patterns without penalizing normal usage:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">SkipSuccessfulRequests</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// only failed attempts count</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="distributed-rate-limiting-with-redis">Distributed Rate Limiting with Redis<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#distributed-rate-limiting-with-redis" class="hash-link" aria-label="Direct link to Distributed Rate Limiting with Redis" title="Direct link to Distributed Rate Limiting with Redis" translate="no">​</a></h2>
<p>The in-memory store works for single instances but falls apart behind a load balancer. If you have three instances each allowing 20 requests per minute, a client gets 60 effective requests.</p>
<p>Plugging in Redis makes the limit shared across instances:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"github.com/gofiber/storage/redis/v3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">store </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">redis</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Host</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"redis.internal"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6379</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Storage</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    store</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Any storage backend from Fiber's <a href="https://github.com/gofiber/storage" target="_blank" rel="noopener noreferrer" class="">storage package</a> works  -  Redis, Memcache, DynamoDB, Postgres. The interface is the same.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="per-route-limiters">Per-Route Limiters<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#per-route-limiters" class="hash-link" aria-label="Direct link to Per-Route Limiters" title="Direct link to Per-Route Limiters" translate="no">​</a></h2>
<p>Sometimes a global middleware is not granular enough. You can apply different limiter instances to different route groups:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Strict limiter for auth routes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">authLimiter </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">               </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    LimiterMiddleware</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SlidingWindow</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Relaxed limiter for public API</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">apiLimiter </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">limiter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Max</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Expiration</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">auth </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Group</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/auth"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">auth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">authLimiter</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">auth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/login"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> loginHandler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">auth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/reset"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> resetHandler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">api </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Group</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/api"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">apiLimiter</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/products"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> listProducts</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/products/:id"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> getProduct</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is cleaner than a single middleware with complex conditional logic, and makes the limits obvious in code review.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If your API has no rate limiting at all, add the one-line default and deploy it. That alone protects against accidental abuse and simple denial-of-service attempts.</p>
<p>Next, identify your sensitive endpoints  -  login, password reset, payment  -  and give them stricter limits with a sliding window. Then add Redis storage when you scale past a single instance.</p>
<p>The goal is not to block legitimate users. It is to make your API predictable under load and expensive to abuse.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-rate-limiting-guide#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/limiter">Limiter Middleware</a></li>
<li class=""><a href="https://github.com/gofiber/storage" target="_blank" rel="noopener noreferrer" class="">Storage Package</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>rate-limiting</category>
            <category>limiter</category>
            <category>security</category>
            <category>api</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Error Handling That Doesn't Embarrass You in Production]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-error-handling-production</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-error-handling-production</guid>
            <pubDate>Sun, 12 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Build a custom error handler in Fiber v3 that keeps your internals hidden while giving clients useful, structured responses.]]></description>
            <content:encoded><![CDATA[<p>The scariest thing in production is not that errors happen. It is that the wrong information leaks when they do.</p>
<p>In Fiber v3, the default error handler sends <code>err.Error()</code> to the client, which can expose a raw database error, an internal file path, or other library-generated details. Panics are a separate concern: Fiber does not recover them by default, so they crash the process unless you enable the Recover middleware. During development, that kind of visibility is helpful. In production, it is a security incident waiting to happen. An attacker learns your ORM, your table schema, maybe even the specific query that failed. All from a 500 response you never thought anyone would read.</p>
<p>Fiber v3's error handling is designed around one idea: handlers return errors, and a central handler decides what the client sees. That separation sounds simple, but it changes how you structure error responses across your entire application.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-the-default-handler-is-not-enough">Why the Default Handler Is Not Enough<a href="https://docs.gofiber.io/blog/fiber-v3-error-handling-production#why-the-default-handler-is-not-enough" class="hash-link" aria-label="Direct link to Why the Default Handler Is Not Enough" title="Direct link to Why the Default Handler Is Not Enough" translate="no">​</a></h2>
<p>Fiber ships with a default error handler that does the right thing for prototyping: it checks if the error is a <code>*fiber.Error</code>, extracts the status code, and sends the error message as plain text.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> DefaultErrorHandler </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    code </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusInternalServerError</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> e </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Error</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">As</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        code </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Code</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">HeaderContentType</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">MIMETextPlainCharsetUTF8</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">code</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The problem is <code>err.Error()</code>. For a <code>fiber.Error</code>, the message is controlled. But for an unexpected error  -  a database timeout, a nil pointer, a failed file operation  -  <code>err.Error()</code> contains whatever the underlying library decided to put in there. That string goes straight to the client.</p>
<p>In one real-world incident, a team discovered that their Postgres connection error included the DSN with credentials. The default handler dutifully sent it as the response body.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="building-a-production-error-handler">Building a Production Error Handler<a href="https://docs.gofiber.io/blog/fiber-v3-error-handling-production#building-a-production-error-handler" class="hash-link" aria-label="Direct link to Building a Production Error Handler" title="Direct link to Building a Production Error Handler" translate="no">​</a></h2>
<p>A production error handler needs to do three things: classify the error, log the details internally, and send a sanitized response to the client.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> APIError </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Code    </span><span class="token builtin">int</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">`json:"code"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Message </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`json:"message"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    TraceID </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`json:"trace_id,omitempty"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ErrorHandler</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        code </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusInternalServerError</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        message </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"An unexpected error occurred"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> e </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Error</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">As</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            code </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Code</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            message </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Message</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Requires: app.Use(requestid.New()) registered before this handler</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Import: "github.com/gofiber/fiber/v3/middleware/requestid"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        traceID </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> requestid</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Log the full error internally  -  never send this to the client</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"[%s] %d %s %s: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            traceID</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> code</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Method</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">code</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">APIError</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            Code</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    code</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            Message</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> message</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            TraceID</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> traceID</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The key insight is the split between <code>err</code> (logged, never exposed) and <code>message</code> (sent to the client, always controlled). If the error is a <code>*fiber.Error</code>, the message was explicitly set by your code. If it is anything else, the client gets a generic message and the real error goes to your logs.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="layered-error-types">Layered Error Types<a href="https://docs.gofiber.io/blog/fiber-v3-error-handling-production#layered-error-types" class="hash-link" aria-label="Direct link to Layered Error Types" title="Direct link to Layered Error Types" translate="no">​</a></h2>
<p>For a larger application, you probably want more than just <code>fiber.Error</code>. Consider a domain-specific error type that carries both public and private information:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> AppError </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    StatusCode </span><span class="token builtin">int</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    PublicMsg  </span><span class="token builtin">string</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Internal   </span><span class="token builtin">error</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">AppError</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Internal </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Internal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PublicMsg</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">NewNotFound</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">msg </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> internal </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">AppError </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">AppError</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        StatusCode</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusNotFound</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        PublicMsg</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  msg</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Internal</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">   internal</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">NewBadRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">msg </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">AppError </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">AppError</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        StatusCode</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusBadRequest</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        PublicMsg</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  msg</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Then your handlers become expressive without leaking internals:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users/:id"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    user</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> db</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FindUser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Params</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Is</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sql</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ErrNoRows</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">NewNotFound</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"User not found"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err </span><span class="token comment" style="color:#999988;font-style:italic">// Will hit the generic "unexpected error" path</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>And the error handler checks for your type first:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">ErrorHandler</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    code </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusInternalServerError</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    message </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"An unexpected error occurred"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> appErr </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">AppError</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> fiberErr </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Error</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">As</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">appErr</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        code </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> appErr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusCode</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        message </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> appErr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PublicMsg</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> appErr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Internal </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"internal: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> appErr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Internal</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">As</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">fiberErr</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        code </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> fiberErr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Code</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        message </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> fiberErr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Message</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">default</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"unhandled: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">code</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">APIError</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Code</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    code</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        Message</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> message</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dont-forget-panics">Don't Forget Panics<a href="https://docs.gofiber.io/blog/fiber-v3-error-handling-production#dont-forget-panics" class="hash-link" aria-label="Direct link to Don't Forget Panics" title="Direct link to Don't Forget Panics" translate="no">​</a></h2>
<p>Fiber does not recover from panics by default. If a nil pointer dereference hits your handler, the entire process crashes. The <code>recover</code> middleware catches panics and converts them to errors that flow through your error handler:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> recoverer </span><span class="token string" style="color:#e3116c">"github.com/gofiber/fiber/v3/middleware/recover"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">recoverer</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Note the import alias: Go's built-in <code>recover</code> keyword conflicts with the package name, so the convention is to import it as <code>recoverer</code>.</p>
<p>With your custom error handler in place, a panic becomes a logged internal error and a clean 500 response instead of a process restart and a confused load balancer.</p>
<p>One subtlety: the recover middleware should be registered early, before other middleware. If it is registered after the logger, panics in the logger itself will not be caught.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="validation-errors-as-structured-responses">Validation Errors as Structured Responses<a href="https://docs.gofiber.io/blog/fiber-v3-error-handling-production#validation-errors-as-structured-responses" class="hash-link" aria-label="Direct link to Validation Errors as Structured Responses" title="Direct link to Validation Errors as Structured Responses" translate="no">​</a></h2>
<p>Validation failures deserve special treatment. A 400 response that says "bad request" is useless to API consumers. They need to know which field failed and why.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> ValidationError </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Field   </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`json:"field"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Message </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`json:"message"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> ValidationErrors </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Errors </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain">ValidationError </span><span class="token string" style="color:#e3116c">`json:"errors"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">ValidationErrors</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sprintf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"%d validation errors"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">len</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Errors</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>In the error handler, check for this type and return a 422:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> validationErr </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">ValidationErrors</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">As</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">validationErr</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusUnprocessableEntity</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">validationErr</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This pattern works well with <code>go-playground/validator</code> or any validation library that returns structured errors.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="content-negotiation">Content Negotiation<a href="https://docs.gofiber.io/blog/fiber-v3-error-handling-production#content-negotiation" class="hash-link" aria-label="Direct link to Content Negotiation" title="Direct link to Content Negotiation" translate="no">​</a></h2>
<p>One detail that is easy to miss: not all clients want JSON. If your application serves both an API and HTML pages, the error handler should respect the <code>Accept</code> header:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Accepts</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"application/json"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">code</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">APIError</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">Code</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> code</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Message</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> message</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">code</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"error"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Code"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    code</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Message"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> message</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This avoids the awkward situation where a browser user sees raw JSON on an error page, or an API client receives HTML it cannot parse.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-error-handling-production#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If your application uses the default error handler, start by adding a custom one that does two things: logs the real error and sends a generic message. That single change eliminates the most common information leakage vector.</p>
<p>Once that is in place, introduce a domain error type for the status codes and messages your handlers use most. You do not need to cover every case on day one.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-error-handling-production#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/guide/error-handling">Error Handling Guide</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/recover">Recover Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>error-handling</category>
            <category>production</category>
            <category>security</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Extractors Guide for Middleware]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-extractors-guide</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-extractors-guide</guid>
            <pubDate>Sat, 21 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Use extractors to centralize value extraction across middleware and improve security consistency.]]></description>
            <content:encoded><![CDATA[<p>Security bugs in middleware are often not algorithm bugs. They are extraction-policy bugs.</p>
<p>One component reads bearer tokens from headers, another falls back to query parameters first, a third uses cookie-first behavior. Each of these can work in isolation, but together they create inconsistent security posture. During an auth migration, the problem multiplies: old services use one extraction path, new services use another, and nobody is sure which fallback order is actually active in production.</p>
<p>The extractors package in Fiber v3 exists to solve this. It gives middleware a shared, composable API for declaring where values come from and in what order, so extraction policy is explicit and reviewable rather than scattered across handler code.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-problem-extractors-replace">The Problem Extractors Replace<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#the-problem-extractors-replace" class="hash-link" aria-label="Direct link to The Problem Extractors Replace" title="Direct link to The Problem Extractors Replace" translate="no">​</a></h2>
<p>Before this package existed, every middleware that needed a token, session ID, or API key implemented its own extraction logic. KeyAuth had its own header parser. Session middleware had its own cookie reader. CSRF had its own form-field lookup. The logic was similar but never identical, and the differences were hard to spot in review.</p>
<p>When a team wanted to change extraction behavior, say adding a fallback from header to cookie during a migration, they had to patch each middleware individually. If one middleware was missed, that endpoint silently used different extraction rules than the rest.</p>
<p>Extractors consolidate this into a single package with a consistent API. Middleware packages import extractors directly, so changes to extraction logic propagate everywhere at once.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="available-extractors">Available Extractors<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#available-extractors" class="hash-link" aria-label="Direct link to Available Extractors" title="Direct link to Available Extractors" translate="no">​</a></h2>
<p>The package provides extractors for every common HTTP source:</p>
<ul>
<li class=""><code>FromAuthHeader(authScheme)</code>  -  extracts from the <code>Authorization</code> header, validating the scheme</li>
<li class=""><code>FromHeader(key)</code>  -  extracts from any request header</li>
<li class=""><code>FromCookie(key)</code>  -  extracts from HTTP cookies</li>
<li class=""><code>FromQuery(param)</code>  -  extracts from URL query parameters</li>
<li class=""><code>FromParam(param)</code>  -  extracts from URL path parameters</li>
<li class=""><code>FromForm(param)</code>  -  extracts from form data (POST body)</li>
<li class=""><code>FromCustom(key, fn)</code>  -  defines custom extraction logic with a callback</li>
<li class=""><code>Chain(extractors...)</code>  -  tries multiple extractors in order, returns the first success</li>
</ul>
<p>Each extractor returns a struct with metadata about the source, not just the value. This means middleware can inspect where a value came from and make security decisions based on source type.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="basic-usage">Basic Usage<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#basic-usage" class="hash-link" aria-label="Direct link to Basic Usage" title="Direct link to Basic Usage" translate="no">​</a></h2>
<p>The simplest case is a single-source extractor passed to middleware config:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">keyauth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">keyauth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-API-Key"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This replaces whatever internal header-parsing logic the middleware previously used, with a shared implementation that behaves identically across all middleware.</p>
<p>For session middleware, the pattern is the same:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromCookie</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"session_id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fallback-chains-declaring-extraction-policy">Fallback Chains: Declaring Extraction Policy<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#fallback-chains-declaring-extraction-policy" class="hash-link" aria-label="Direct link to Fallback Chains: Declaring Extraction Policy" title="Direct link to Fallback Chains: Declaring Extraction Policy" translate="no">​</a></h2>
<p>The real power shows up when you need multiple sources. During auth migrations, for example, you might accept tokens from the <code>Authorization</code> header (the new path) while still supporting a legacy <code>X-API-Key</code> header and a query parameter fallback for internal tools.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">keyauth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">keyauth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Chain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromAuthHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Bearer"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-API-Key"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromQuery</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"api_key"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><code>Chain</code> tries each extractor in order. The first one that returns a non-empty value without error wins. If all extractors fail, it returns the last error or <code>ErrNotFound</code>.</p>
<p>The ordering is policy. Putting the <code>Authorization</code> header first means that if both a header and a query parameter are present, the header wins. That is a deliberate security decision, and it lives in code rather than in documentation that nobody reads.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="authorization-header-and-rfc-compliance">Authorization Header and RFC Compliance<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#authorization-header-and-rfc-compliance" class="hash-link" aria-label="Direct link to Authorization Header and RFC Compliance" title="Direct link to Authorization Header and RFC Compliance" translate="no">​</a></h2>
<p>The <code>FromAuthHeader</code> extractor is not a simple string split. It implements RFC 9110 Section 11.6.2 and RFC 7235 token68 validation:</p>
<ul>
<li class="">Case-insensitive scheme matching (<code>Bearer</code>, <code>bearer</code>, <code>BEARER</code> all work)</li>
<li class="">Strict whitespace handling (only spaces between scheme and token, no tabs)</li>
<li class="">Token68 character validation (only <code>A-Z</code>, <code>a-z</code>, <code>0-9</code>, <code>-._~+/=</code>)</li>
<li class="">Padding rules (trailing <code>=</code> only, never leading or mid-token)</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">extractor </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromAuthHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Bearer"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Valid: "Bearer abc123" → "abc123"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Valid: "bearer ABC123" → "ABC123" (case-insensitive)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Invalid: "Bearer abc def" → rejected (space in token)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Invalid: "Bearer =abc" → rejected (padding at start)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Invalid: "Bearertoken" → rejected (no space after scheme)</span><br></div></code></pre></div></div>
<p>This strictness matters because malformed authorization headers are a common vector for authentication bypass. A permissive parser might accept a header that a standards-compliant proxy would reject, creating inconsistency between your application layer and your infrastructure.</p>
<p>If you need raw header access without validation, pass an empty scheme:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">raw </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromAuthHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Returns the full header value without scheme parsing</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="security-considerations-by-source">Security Considerations by Source<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#security-considerations-by-source" class="hash-link" aria-label="Direct link to Security Considerations by Source" title="Direct link to Security Considerations by Source" translate="no">​</a></h2>
<p>Different extraction sources have different security properties, and the choice is not just about convenience.</p>
<p><strong>Headers</strong> are generally preferred for sensitive values. They are not visible in URLs, not stored in browser history, and not logged by default in most proxy configurations. The <code>Authorization</code> header is the standard place for credentials.</p>
<p><strong>Cookies</strong> are designed for persistent client-side storage and support <code>Secure</code>, <code>HttpOnly</code>, and <code>SameSite</code> flags. They are the right choice for session tokens, but require correct flag configuration to be safe.</p>
<p><strong>Query parameters</strong> are always visible in URLs. They get logged by servers, stored in browser history, cached by proxies, and appear in referrer headers. Never put sensitive tokens in query parameters unless there is no alternative.</p>
<p><strong>Form data</strong> is suitable for user-generated content and CSRF tokens in form submissions, but requires POST requests and correct content types.</p>
<p>When building chains, order them from most secure to least secure:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Chain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromAuthHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Bearer"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// standard, secure</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromCookie</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"auth_token"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// persistent, needs flags</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromQuery</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"token"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">          </span><span class="token comment" style="color:#999988;font-style:italic">// visible, use sparingly</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="csrf-middleware-example">CSRF Middleware Example<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#csrf-middleware-example" class="hash-link" aria-label="Direct link to CSRF Middleware Example" title="Direct link to CSRF Middleware Example" translate="no">​</a></h2>
<p>CSRF protection is a good example of where chains solve a real problem. Header-based CSRF tokens work for AJAX and API clients, but traditional form submissions need form-field extraction:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">csrf</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Chain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-CSRF-Token"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromForm</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"_csrf"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This supports both JavaScript clients that set headers and HTML forms that submit tokens in hidden fields, with a single consistent config.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="custom-extractors-for-special-cases">Custom Extractors for Special Cases<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#custom-extractors-for-special-cases" class="hash-link" aria-label="Direct link to Custom Extractors for Special Cases" title="Direct link to Custom Extractors for Special Cases" translate="no">​</a></h2>
<p>When standard extractors do not fit, <code>FromCustom</code> lets you define arbitrary extraction logic:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">extractor </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromCustom</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"computed-token"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> val </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Locals</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"computed_token"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> val </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> val</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ErrNotFound</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Custom extractors break source awareness: middleware cannot determine where the value came from, so automatic security warnings and source-based logging will not work. Use them only when standard extractors do not meet your needs and you have evaluated the security implications.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="coordinating-multiple-middleware">Coordinating Multiple Middleware<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#coordinating-multiple-middleware" class="hash-link" aria-label="Direct link to Coordinating Multiple Middleware" title="Direct link to Coordinating Multiple Middleware" translate="no">​</a></h2>
<p>When several middleware packages extract values from the same request, make sure they use different sources to avoid conflicts:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Good: different sources for different purposes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">keyauth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">keyauth</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-API-Key"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Config</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Extractor</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> extractors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromCookie</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"session_id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>If two middleware packages extract from the same cookie or header, one will shadow the other and debugging becomes unpredictable.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If your middleware currently uses hardcoded extraction logic, pick the authentication middleware first. Replace its internal token lookup with an extractor, then verify that fallback behavior matches what you expect. Once that works, move to session and CSRF middleware.</p>
<p>The goal is not to rewrite everything at once. The goal is to make extraction policy visible and consistent, one middleware at a time.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-extractors-guide#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/guide/extractors">Extractors Guide</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/keyauth">KeyAuth Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>extractors</category>
            <category>middleware</category>
            <category>security</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Hooks Guide for Clean Lifecycles]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-hooks-guide</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-hooks-guide</guid>
            <pubDate>Fri, 20 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Use hooks to control startup, shutdown, and operational lifecycle more reliably.]]></description>
            <content:encoded><![CDATA[<p>Many runtime incidents happen during transitions, not steady state.</p>
<p>A service is starting up, shutting down, draining workers, or flushing telemetry, and behavior is only partially defined. If your deploy process relies on conventions like "we always flush metrics before exit," but nobody enforced that in code, you get data loss during rollouts. If startup checks happen in scattered goroutines, a failing dependency might not block listen, and you serve errors for the first few seconds after deploy.</p>
<p>Fiber v3 hooks give that lifecycle a concrete structure. Instead of hoping everyone follows the same script, you can register pre and post handlers for startup and shutdown and make the behavior reviewable.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-v2-lifecycle-looked-like">What v2 Lifecycle Looked Like<a href="https://docs.gofiber.io/blog/fiber-v3-hooks-guide#what-v2-lifecycle-looked-like" class="hash-link" aria-label="Direct link to What v2 Lifecycle Looked Like" title="Direct link to What v2 Lifecycle Looked Like" translate="no">​</a></h2>
<p>In v2, the main lifecycle hook was <code>OnShutdown</code>. It ran during server shutdown, but you had no way to distinguish "before the server stops accepting" from "after everything is drained." Teams often worked around this with manual signal handling:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// v2-era pattern: manual signal handling outside Fiber</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">quit </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">make</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">chan</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Signal</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">signal</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Notify</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">quit</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGINT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> syscall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SIGTERM</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">go</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&lt;-</span><span class="token plain">quit</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"stopping workers..."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// hope this runs before Shutdown</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">stopConsumers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Shutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Listen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">":3000"</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The problem was ordering. You could not guarantee that worker drain happened before or after the server stopped, and the shutdown error was invisible unless you wired it yourself.</p>
<p>v3 replaces <code>OnShutdown</code> with explicit <code>OnPreShutdown</code> and <code>OnPostShutdown</code> hooks, and adds startup message hooks that give you a real contract for each phase.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="startup-message-customization">Startup Message Customization<a href="https://docs.gofiber.io/blog/fiber-v3-hooks-guide#startup-message-customization" class="hash-link" aria-label="Direct link to Startup Message Customization" title="Direct link to Startup Message Customization" translate="no">​</a></h2>
<p>One of the most practical additions is the ability to customize the startup banner. In production, the default Fiber banner is noise. In staging, you want environment context visible immediately when a pod starts.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnPreStartupMessage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sm </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PreStartupMessageData</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">BannerHeader </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"MY-SERVICE "</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> sm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Version </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"\n-------"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">AddInfo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"region"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Region"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"AWS_REGION"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">AddInfo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"release"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Release"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"RELEASE_SHA"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    sm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">AddWarning</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"debug"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Debug mode"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"enabled"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnPostStartupMessage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sm </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PostStartupMessageData</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">sm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Disabled </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">sm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">IsChild </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">sm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Prevented </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"startup banner printed, service ready"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Inside <code>OnPreStartupMessage</code> you have full control:</p>
<ul>
<li class=""><code>sm.BannerHeader</code> replaces the ASCII art banner</li>
<li class=""><code>sm.AddInfo</code>, <code>sm.AddWarning</code>, <code>sm.AddError</code> add labeled entries</li>
<li class=""><code>sm.ResetEntries()</code> clears all default entries if you want a clean slate</li>
<li class=""><code>sm.PreventDefault = true</code> suppresses the banner entirely without affecting other hooks</li>
</ul>
<p>The <code>PostStartupMessageData</code> gives you flags to check whether the banner was actually printed (<code>Disabled</code>, <code>IsChild</code>, <code>Prevented</code>), so you can gate post-startup logic accordingly.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="shutdown-hooks-with-clear-phases">Shutdown Hooks with Clear Phases<a href="https://docs.gofiber.io/blog/fiber-v3-hooks-guide#shutdown-hooks-with-clear-phases" class="hash-link" aria-label="Direct link to Shutdown Hooks with Clear Phases" title="Direct link to Shutdown Hooks with Clear Phases" translate="no">​</a></h2>
<p>The shutdown hooks split a single event into two phases with different responsibilities:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnPreShutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Println</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"pre-shutdown: stop accepting new work"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">stopConsumers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnPostShutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"shutdown had errors: %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">alertOps</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">flushMetrics</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><code>OnPreShutdown</code> runs before the server finishes shutting down. This is where you stop queue consumers, cancel background workers, and drain in-flight requests.</p>
<p><code>OnPostShutdown</code> runs after the server is down and receives the shutdown error. This is where you flush metrics, close database pools, and send final telemetry. The error parameter tells you whether shutdown was clean or not, so you can adjust your cleanup accordingly.</p>
<p>Important: when using shutdown hooks, <code>app.Listen()</code> must run in a goroutine so <code>app.Shutdown()</code> is reachable:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">go</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Listen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">":3000"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ... signal handling ...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Shutdown</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="route-and-group-registration-hooks">Route and Group Registration Hooks<a href="https://docs.gofiber.io/blog/fiber-v3-hooks-guide#route-and-group-registration-hooks" class="hash-link" aria-label="Direct link to Route and Group Registration Hooks" title="Direct link to Route and Group Registration Hooks" translate="no">​</a></h2>
<p>Beyond lifecycle, Fiber v3 also provides hooks that fire during route registration. These are useful for building route registries, auto-generating documentation, or enforcing naming conventions at startup time.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnRoute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Route</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"registered: %s %s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Method</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Path</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnGroup</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">g fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Group</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"group registered: %s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> g</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Prefix</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><code>OnName</code> fires when a route is named via <code>.Name()</code>, which is useful for building route registries or logging named routes:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Route</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"named route registered: %s %s → %s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Method</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Path</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> listUsers</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Name</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"listUsers"</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>If you want to enforce that <em>all</em> routes have names, use <code>OnRoute</code> instead  -  it fires for every registration regardless of whether <code>.Name()</code> was called:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnRoute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Route</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Errorf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"route %s %s must have a name"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Method</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Path</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="mount-hooks-for-sub-applications">Mount Hooks for Sub-Applications<a href="https://docs.gofiber.io/blog/fiber-v3-hooks-guide#mount-hooks-for-sub-applications" class="hash-link" aria-label="Direct link to Mount Hooks for Sub-Applications" title="Direct link to Mount Hooks for Sub-Applications" translate="no">​</a></h2>
<p>When you compose applications from sub-apps, <code>OnMount</code> fires after a child app is mounted. The callback receives the parent app, so you can inspect or modify the parent during composition:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">api </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Hooks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">OnMount</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">parent </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">App</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Printf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"api mounted at: %s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> parent</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">MountPath</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/api"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> api</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is useful for plugin-style architectures where sub-apps need to register shared middleware or verify parent configuration before they start serving.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="putting-it-together-a-production-lifecycle">Putting It Together: A Production Lifecycle<a href="https://docs.gofiber.io/blog/fiber-v3-hooks-guide#putting-it-together-a-production-lifecycle" class="hash-link" aria-label="Direct link to Putting It Together: A Production Lifecycle" title="Direct link to Putting It Together: A Production Lifecycle" translate="no">​</a></h2>
<p>Here is what a realistic lifecycle setup looks like when you combine several hooks:</p>
<!-- -->
<p>The key insight is that each phase has a clear owner. You can review lifecycle behavior in a pull request the same way you review business logic, because it lives in code with explicit ordering.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-start">Where to Start<a href="https://docs.gofiber.io/blog/fiber-v3-hooks-guide#where-to-start" class="hash-link" aria-label="Direct link to Where to Start" title="Direct link to Where to Start" translate="no">​</a></h2>
<p>If your service currently has no lifecycle hooks, start with two:</p>
<ol>
<li class=""><code>OnPreShutdown</code> to drain background work before exit</li>
<li class=""><code>OnPostShutdown</code> to flush telemetry and confirm clean shutdown</li>
</ol>
<p>That alone eliminates the most common class of deploy-related data loss. Once that works, add startup message customization so your team can see environment context in logs without grepping for it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-hooks-guide#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/api/hooks">Hooks API</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>hooks</category>
            <category>lifecycle</category>
            <category>operations</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[Handler Compatibility in the New Router]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-adapter-pattern</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-adapter-pattern</guid>
            <pubDate>Thu, 19 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How Fiber's new router compatibility layer lets you use Fiber, net/http, and fasthttp handlers side by side.]]></description>
            <content:encoded><![CDATA[<p>One of the most underrated improvements in the v3 router is not a new method or fancy syntax. It is <strong>handler compatibility</strong>.</p>
<p>In plain terms: Fiber can now accept multiple handler styles directly, and the router compatibility layer adapts them for you. That sounds small until you are migrating a real codebase with hundreds of handlers, middleware functions, and utility packages in different styles. Then it becomes the feature that decides whether migration happens this quarter or gets postponed again.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-migration-problem-this-solves">The Migration Problem This Solves<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#the-migration-problem-this-solves" class="hash-link" aria-label="Direct link to The Migration Problem This Solves" title="Direct link to The Migration Problem This Solves" translate="no">​</a></h2>
<p>For a deep dive into the Express-style <code>Req</code>/<code>Res</code> handler pattern specifically, see <a class="" href="https://docs.gofiber.io/blog/fiber-v3-express-style-handlers">Express-Style Handlers in Go</a>. This post focuses on the broader handler compatibility model and migration strategy.</p>
<p>Most teams do not start from a greenfield codebase. They have <code>net/http</code> handlers written years ago, <code>fasthttp</code> handlers from performance-critical paths, middleware contracts in various styles, and helper functions that mix handler signatures.</p>
<p>Before this compatibility model, migration usually meant one of two painful paths:</p>
<ul>
<li class="">Rewrite all handler signatures upfront, even when business logic had not changed. This creates a large, risky PR that touches every endpoint.</li>
<li class="">Maintain local custom adapters that wrap old handlers. These wrappers are inconsistent across modules, and nobody cleans them up after migration.</li>
</ul>
<p>Both approaches increase risk and slow down migration. The v3 compatibility layer eliminates this tradeoff by accepting supported handler shapes directly in the router.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="supported-handler-styles">Supported Handler Styles<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#supported-handler-styles" class="hash-link" aria-label="Direct link to Supported Handler Styles" title="Direct link to Supported Handler Styles" translate="no">​</a></h2>
<p>The router adapter understands 17 handler signatures across four families:</p>
<p><strong>Native Fiber handlers</strong>  -  the cleanest long-term choice:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/health"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"ok"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><strong>Standard library <code>net/http</code> handlers</strong>  -  for legacy code and ecosystem packages:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">mux </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewServeMux</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">mux</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">HandleFunc</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/legacy"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">w http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ResponseWriter</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteHeader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">http</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusOK</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">_</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Write</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token function" style="color:#d73a49">byte</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"legacy route"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/legacy"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> mux</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ServeHTTP</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is especially useful when one route still depends on old middleware or legacy packages that only expose <code>http.Handler</code> interfaces.</p>
<p><strong><code>fasthttp</code> handlers</strong>  -  for existing performance-critical code:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/fast"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">fasthttp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">RequestCtx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ctx</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SetStatusCode</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fasthttp</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">StatusOK</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">_</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ctx</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WriteString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fast path"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><strong>Express-style <code>Req</code>/<code>Res</code> handlers</strong>  -  for teams migrating from Express or who prefer that mental model:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-Trace-Source"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"compat-layer"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/hello"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Req</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> res fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Res</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> res</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The Express-style callbacks support both two-argument (handler) and three-argument (middleware with <code>next</code>) forms, with or without error returns. The adapter also supports <code>next</code> callbacks that accept errors (<code>func(error)</code> or <code>func(error) error</code>), so middleware control flow works across all styles.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-next-wiring-works">How <code>next</code> Wiring Works<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#how-next-wiring-works" class="hash-link" aria-label="Direct link to how-next-wiring-works" title="Direct link to how-next-wiring-works" translate="no">​</a></h2>
<p>A subtle but important detail is how <code>next</code> is connected across handler styles. When you use optional <code>next</code> callbacks in Express-style handlers, Fiber wires them to <code>c.Next()</code> internally:</p>
<ul>
<li class="">Calling <code>next(nil)</code> (or <code>next()</code> for the no-argument variant) continues the middleware chain</li>
<li class="">Passing a non-nil error to <code>next(err)</code> short-circuits and returns that error</li>
<li class="">If your handler returns an <code>error</code>, the value returned from the injected <code>next()</code> bubbles straight back to the caller</li>
</ul>
<p>This means middleware behavior follows expected control flow even when handlers use different signature styles. A <code>net/http</code> middleware and an Express-style middleware in the same chain will propagate errors consistently.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="routechain-express-style-route-declaration">RouteChain: Express-style Route Declaration<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#routechain-express-style-route-declaration" class="hash-link" aria-label="Direct link to RouteChain: Express-style Route Declaration" title="Direct link to RouteChain: Express-style Route Declaration" translate="no">​</a></h2>
<p>Beyond handler compatibility, the v3 router also adds <code>RouteChain</code>, a helper inspired by <a href="https://expressjs.com/en/api.html#app.route" target="_blank" rel="noopener noreferrer" class="">Express's <code>app.route()</code></a> that lets you declare multiple HTTP methods on the same path without repeating it:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">RouteChain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/api"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">RouteChain</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/user/:id?"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"action"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"get user"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Params</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Post</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"action"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"create user"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Put</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"action"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"update user"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Params</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">Delete</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Map</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"action"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"delete user"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Params</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is particularly clean for resource-style APIs where GET, POST, PUT, and DELETE all operate on the same path.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="automatic-head-routes">Automatic HEAD Routes<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#automatic-head-routes" class="hash-link" aria-label="Direct link to Automatic HEAD Routes" title="Direct link to Automatic HEAD Routes" translate="no">​</a></h2>
<p>Fiber v3 auto-registers a <code>HEAD</code> route for every <code>GET</code> route. The generated handler chain matches the <code>GET</code> chain, so status codes and headers stay in sync while the response body remains empty:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/health"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"X-Service"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"api"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"OK"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// HEAD /health automatically returns headers without body</span><br></div></code></pre></div></div>
<p>You can still register explicit <code>HEAD</code> handlers to override the generated ones, and you can disable this entirely with <code>fiber.Config{DisableHeadAutoRegister: true}</code> if you prefer to manage HEAD routes yourself.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="stricter-middleware-prefix-matching">Stricter Middleware Prefix Matching<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#stricter-middleware-prefix-matching" class="hash-link" aria-label="Direct link to Stricter Middleware Prefix Matching" title="Direct link to Stricter Middleware Prefix Matching" translate="no">​</a></h2>
<p>The v3 router aligns middleware registration closer to Express. Prefix matching is now stricter: partial matches must end at a slash boundary or be an exact match. This prevents <code>/api</code> middleware from accidentally running on <code>/apiv1</code>:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// This middleware only runs for /api and /api/... paths</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// It does NOT run for /apiv1 or /api-internal</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/api"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> apiMiddleware</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>You can also register middleware for multiple prefixes at once:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"/v1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/v2"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>And sub-apps can be mounted with <code>app.Use()</code> instead of the old <code>app.Mount()</code>:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">api </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">api</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/users"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> listUsers</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/api"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> api</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-practical-migration-pattern">A Practical Migration Pattern<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#a-practical-migration-pattern" class="hash-link" aria-label="Direct link to A Practical Migration Pattern" title="Direct link to A Practical Migration Pattern" translate="no">​</a></h2>
<p>A migration pattern that works well in real teams:</p>
<ol>
<li class=""><strong>Keep legacy routes operational</strong> using compatibility handlers. Register existing <code>net/http</code> or <code>fasthttp</code> handlers directly in the Fiber router. No wrappers needed.</li>
<li class=""><strong>Migrate high-traffic routes first</strong> to native Fiber handlers. These benefit most from Fiber-specific APIs like binding, custom context, and hooks.</li>
<li class=""><strong>Remove compatibility paths</strong> once ownership and test coverage are stable.</li>
</ol>
<!-- -->
<p>The important point is that compatibility is a <strong>transition tool</strong>, not a permanent architecture target. Native Fiber handlers are the right long-term choice for hot paths, new endpoints, and code that uses Fiber-specific context APIs.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-to-prefer-native-fiber-immediately">When to Prefer Native Fiber Immediately<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#when-to-prefer-native-fiber-immediately" class="hash-link" aria-label="Direct link to When to Prefer Native Fiber Immediately" title="Direct link to When to Prefer Native Fiber Immediately" translate="no">​</a></h2>
<p>Even with compatibility support, choose native Fiber handlers for:</p>
<ul>
<li class="">New endpoints (no legacy code to preserve)</li>
<li class="">Performance-sensitive paths (native handlers avoid adapter overhead)</li>
<li class="">Code that needs binding, custom context, or hooks</li>
</ul>
<p>Use compatibility where it reduces migration risk, not where it increases long-term complexity.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-adapter-pattern#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class="">Official section: <a class="" href="https://docs.gofiber.io/whats_new#handler-compatibility">What's New: Handler compatibility</a></li>
<li class="">API docs: <a class="" href="https://docs.gofiber.io/api/app">App Router Methods</a></li>
<li class="">Middleware docs: <a class="" href="https://docs.gofiber.io/middleware/adaptor">Adaptor Middleware</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>router</category>
            <category>handler</category>
            <category>compatibility</category>
            <category>migration</category>
            <category>go</category>
        </item>
        <item>
            <title><![CDATA[RFC Conformance in Practice]]></title>
            <link>https://docs.gofiber.io/blog/fiber-v3-rfc-conformance</link>
            <guid>https://docs.gofiber.io/blog/fiber-v3-rfc-conformance</guid>
            <pubDate>Wed, 18 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why RFC-aligned behavior matters for interoperability, caching, and security.]]></description>
            <content:encoded><![CDATA[<p>RFC conformance can sound abstract until you run a real production stack.</p>
<p>Your service is not only interacting with one client. It is sitting behind load balancers, reverse proxies, CDNs, API gateways, browsers, mobile clients, and internal automation tools. A cookie that works in Chrome but breaks in Safari, a cache header that your CDN interprets differently than you intended, an authorization header that your proxy strips because it does not match the expected format  -  these are real incidents that happen because of small protocol deviations.</p>
<p>Fiber v3 addresses this with specific improvements to cookie handling, context behavior, response semantics, and connection management, each tied to concrete RFCs. This post walks through what changed and why it matters operationally.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cookie-security-samesitenone-and-automatic-secure-flag">Cookie Security: SameSite=None and Automatic Secure Flag<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#cookie-security-samesitenone-and-automatic-secure-flag" class="hash-link" aria-label="Direct link to Cookie Security: SameSite=None and Automatic Secure Flag" title="Direct link to Cookie Security: SameSite=None and Automatic Secure Flag" translate="no">​</a></h2>
<p>Modern browsers (Chrome, Firefox, Safari) reject cookies that set <code>SameSite=None</code> without the <code>Secure</code> flag. This is required by RFC 6265bis and enforced by all major browsers since 2020.</p>
<p>In v2, teams had to remember to set both flags manually. Forgetting <code>Secure</code> on a cross-site cookie was a silent failure: the cookie just disappeared in the browser without any server-side error.</p>
<p>Fiber v3 enforces this automatically. When you set <code>SameSite=None</code>, Fiber sets <code>Secure=true</code> for you:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Cookie</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Cookie</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"session"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Value</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    token</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    HTTPOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    SameSite</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"None"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Secure is automatically set to true by Fiber</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This eliminates an entire class of "cookies don't work in production but work locally" bugs, because local development typically uses HTTP while production uses HTTPS.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="chips-partitioned-cookies-for-privacy">CHIPS: Partitioned Cookies for Privacy<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#chips-partitioned-cookies-for-privacy" class="hash-link" aria-label="Direct link to CHIPS: Partitioned Cookies for Privacy" title="Direct link to CHIPS: Partitioned Cookies for Privacy" translate="no">​</a></h2>
<p>Fiber v3 also supports Partitioned cookies for <a href="https://developers.google.com/privacy-sandbox/3pcd/chips" target="_blank" rel="noopener noreferrer" class="">CHIPS</a> (Cookies Having Independent Partitioned State). This is a newer browser feature that partitions cookies by top-level site, preventing cross-site tracking while still allowing legitimate third-party cookie use.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Cookie</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Cookie</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">        </span><span class="token string" style="color:#e3116c">"widget_session"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Value</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">       token</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    HTTPOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Secure</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    SameSite</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"None"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Partitioned</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>If your service embeds widgets, authentication flows, or tracking pixels in third-party sites, partitioned cookies let you maintain session state without being blocked by third-party cookie restrictions. Without CHIPS support, these use cases break progressively as browsers roll out stricter cookie policies.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="context-implements-contextcontext">Context Implements context.Context<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#context-implements-contextcontext" class="hash-link" aria-label="Direct link to Context Implements context.Context" title="Direct link to Context Implements context.Context" translate="no">​</a></h2>
<p>One of the more subtle but impactful changes: <code>fiber.Ctx</code> now implements Go's standard <code>context.Context</code> interface. This means you can pass the Fiber context directly to functions that expect a <code>context.Context</code>, including database drivers, HTTP clients, and tracing libraries.</p>
<p>In v2, you had to use <code>c.UserContext()</code> and <code>c.SetUserContext()</code> to bridge between Fiber and the standard library:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// v2: manual context bridging</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ctx </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">UserContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">rows</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> db</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">QueryContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"SELECT ..."</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>In v3, the context is the context:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// v3: Fiber context is a context.Context</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">rows</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> db</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">QueryContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"SELECT ..."</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This matters for deadline propagation, cancellation, and request-scoped values. Libraries that accept <code>context.Context</code> now get proper request lifecycle integration without boilerplate. If a request is cancelled, the context signals it. If a deadline is set, downstream calls respect it.</p>
<p>You can still set a base context with <code>c.SetContext()</code> if you need to inject values or deadlines before passing <code>c</code> to downstream code. And <code>c.Context()</code> returns a <code>context.Context</code> that is safe to use outside the handler scope.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sendearlyhints-http-103-for-resource-preloading">SendEarlyHints: HTTP 103 for Resource Preloading<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#sendearlyhints-http-103-for-resource-preloading" class="hash-link" aria-label="Direct link to SendEarlyHints: HTTP 103 for Resource Preloading" title="Direct link to SendEarlyHints: HTTP 103 for Resource Preloading" translate="no">​</a></h2>
<p>Fiber v3 supports <a href="https://developer.chrome.com/docs/web-platform/early-hints" target="_blank" rel="noopener noreferrer" class="">HTTP 103 Early Hints</a>, an informational response that lets the server send <code>Link</code> headers before the final response is ready. This allows browsers to start preloading critical assets while the server is still computing the response.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/dashboard"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    hints </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"&lt;https://cdn.example.com/app.js&gt;; rel=preload; as=script"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"&lt;https://cdn.example.com/style.css&gt;; rel=preload; as=style"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendEarlyHints</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">hints</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// expensive computation or DB query here</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    data </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">loadDashboard</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">JSON</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>For pages with heavy asset loads, early hints can measurably improve perceived load time because the browser starts fetching CSS and JavaScript while the server is still preparing HTML or API data.</p>
<p>Note: older HTTP/1.1 clients may ignore or mishandle 103 responses. This is most effective with HTTP/2 and HTTP/3 deployments.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="drop-silent-connection-termination">Drop: Silent Connection Termination<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#drop-silent-connection-termination" class="hash-link" aria-label="Direct link to Drop: Silent Connection Termination" title="Direct link to Drop: Silent Connection Termination" translate="no">​</a></h2>
<p>The <code>Drop</code> method terminates a client connection without sending any HTTP response. No headers, no status code, no body. The client sees a connection reset.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Use</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">isBlocked</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IP</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Drop</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is useful for DDoS mitigation and endpoint protection where you want to reveal as little information as possible to the attacker. A normal 403 or 429 response confirms the endpoint exists and tells the attacker their request reached the application layer. <code>Drop</code> gives them nothing.</p>
<p>This should complement, not replace, infrastructure-level protections like firewalls and rate limiters. But for application-layer blocking, it is a meaningful improvement over returning error responses.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="end-immediate-connection-flush">End: Immediate Connection Flush<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#end-immediate-connection-flush" class="hash-link" aria-label="Direct link to End: Immediate Connection Flush" title="Direct link to End: Immediate Connection Flush" translate="no">​</a></h2>
<p>The <code>End</code> method, modeled after Express.js <code>res.end()</code>, immediately flushes the response and closes the connection. Any middleware that runs after the handler cannot modify the response:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/webhook"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">c fiber</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SendString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"accepted"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> c</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">End</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// response is sent, connection closed</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// downstream middleware cannot change the response</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>This is useful for webhook endpoints and fire-and-forget patterns where you want to acknowledge the request immediately without risking response modification from error-handling middleware.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="non-ascii-filenames-in-downloads">Non-ASCII Filenames in Downloads<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#non-ascii-filenames-in-downloads" class="hash-link" aria-label="Direct link to Non-ASCII Filenames in Downloads" title="Direct link to Non-ASCII Filenames in Downloads" translate="no">​</a></h2>
<p>Fiber v3 now uses <code>filename*</code> encoding per <a href="https://www.rfc-editor.org/rfc/rfc6266" target="_blank" rel="noopener noreferrer" class="">RFC 6266</a> and <a href="https://www.rfc-editor.org/rfc/rfc8187" target="_blank" rel="noopener noreferrer" class="">RFC 8187</a> for non-ASCII filenames in <code>Attachment</code> and <code>Download</code> responses. This means filenames with Unicode characters render correctly in all modern browsers instead of being garbled or replaced with fallback names.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-apply-this-after-upgrading">Where to Apply This After Upgrading<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#where-to-apply-this-after-upgrading" class="hash-link" aria-label="Direct link to Where to Apply This After Upgrading" title="Direct link to Where to Apply This After Upgrading" translate="no">​</a></h2>
<p>A practical first step after migrating to v3 is a response-policy audit:</p>
<ol>
<li class=""><strong>Cookies</strong>: Review all <code>Set-Cookie</code> calls. Confirm that cross-site cookies use <code>SameSite=None</code> (v3 handles <code>Secure</code> automatically). Consider <code>Partitioned</code> for third-party contexts.</li>
<li class=""><strong>Cache headers</strong>: Verify cache behavior matches your CDN and proxy expectations. The <a class="" href="https://docs.gofiber.io/middleware/cache">cache middleware</a> updates in v3 align more closely with standard semantics.</li>
<li class=""><strong>Auth headers</strong>: If you use the extractors package, the <code>FromAuthHeader</code> extractor now validates tokens per RFC 9110 and RFC 7235.</li>
<li class=""><strong>Download endpoints</strong>: Test with non-ASCII filenames to confirm proper encoding.</li>
</ol>
<p>Teams that do this audit once usually prevent an entire class of "works in one client but not another" incidents.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="internal-references">Internal References<a href="https://docs.gofiber.io/blog/fiber-v3-rfc-conformance#internal-references" class="hash-link" aria-label="Direct link to Internal References" title="Direct link to Internal References" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.gofiber.io/whats_new">What's New</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/api/ctx">Ctx API</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/cache">Cache Middleware</a></li>
<li class=""><a class="" href="https://docs.gofiber.io/middleware/static">Static Middleware</a></li>
</ul>]]></content:encoded>
            <category>fiber</category>
            <category>v3</category>
            <category>rfc</category>
            <category>http</category>
            <category>security</category>
            <category>go</category>
        </item>
    </channel>
</rss>