Fail-open vs fail-closed: the security decision you make without realizing it
If you build software long enough, you eventually ship a bug that isn't a typo or a logic error — it's a default. Specifically, it's the answer to a question nobody asked out loud: "What happens when this check fails?" That question has a name in security engineering: fail-open vs fail-closed. Pictu

If you build software long enough, you eventually ship a bug that isn't a typo or a logic error — it's a default. Specifically, it's the answer to a question nobody asked out loud: "What happens when this check fails?" That question has a name in security engineering: fail-open vs fail-closed. Picture a badge-controlled office door. Normally you need a card to get in. Then the power dies and the lock controller crashes. In that instant the door has to "decide": swing open so people can move freely, or stay locked so no one gets through. Swinging open is fail-open. Staying locked is fail-closed. Neither is universally correct. A fire exit is designed to fail-open — in an emergency, human life beats access control. A bank vault is the opposite: it fails closed, because a vault that pops open when the system glitches defeats its entire purpose. Say your auth service goes down mid-request. What does your app do? // Fail-open: keep serving, but the door is wide open async function authorize(req: Request): Promise<boolean> { try { return await authService.check(req.token); } catch (err) { logger.warn("auth check failed, allowing request", err); return true; // an attacker's dream } } // Fail-closed: deny by default when anything is uncertain async function authorize(req: Request): Promise<boolean> { try { return await authService.check(req.token); } catch (err) { logger.error("auth check failed, denying request", err); return false; // safe, even if annoying } } Fail-open keeps the site alive at the cost of letting everyone in. Fail-closed keeps attackers out at the cost of locking real users out too. This is the classic trade-off between availability and security, and the whole point is that you have to pick a side on purpose — not leave it to a stray catch block. The more sensitive the thing, the more it should fail-closed. Payment gateways, authentication layers, data-access checks — when these break, the default must be "deny", because a single fail-open here can cost you the whole system. The inverse is also true. Auxiliary concerns — logging, notifications, analytics — should usually fail-open. If your metrics pipeline goes down, blocking the entire app over it is the actual bug. At LumiBase, the Content OS I'm building in public, this decision shows up everywhere — and it gets sharper once AI agents operate content on your behalf. An agent that wants to publish or delete content touches a schema:write-class capability. If the approval service or policy check is unavailable, the agent must fail-closed: no write happens, the action lands in an approval queue, and a human keeps the veto. Failing open here would mean an autonomous agent shipping changes to production content while your guardrails are offline — exactly the nightmare scenario a headless CMS should never allow. Meanwhile, the parts that only observe — provenance logging, reconciliation telemetry, usage stats — fail-open. A hiccup in the audit stream should never stop a legitimate content operation. Fail-open vs fail-closed isn't about which one is "better". It's about whether you chose at all. The scariest vulnerabilities are rarely dramatic — they're the quiet spots where a developer never asked "what happens when this breaks?", and the system silently failed open while everyone assumed it was safe. Ask the question early. Make the default explicit. Your future incident report will thank you.
Key Takeaways
- •If you build software long enough, you eventually ship a bug that isn't a typo or a logic error — it's a default
- •This story was reported by Dev.to, covering developments in the dev space.
- •AI advancements continue to reshape industries — read the full article on Dev.to for complete coverage.
📖 Continue reading the full article:
Read Full Article on Dev.to →

